pkcs11.c 175 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. /*
  5. * This file implements PKCS 11 on top of our existing security modules
  6. *
  7. * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
  8. * This implementation has two slots:
  9. * slot 1 is our generic crypto support. It does not require login.
  10. * It supports Public Key ops, and all they bulk ciphers and hashes.
  11. * It can also support Private Key ops for imported Private keys. It does
  12. * not have any token storage.
  13. * slot 2 is our private key support. It requires a login before use. It
  14. * can store Private Keys and Certs as token objects. Currently only private
  15. * keys and their associated Certificates are saved on the token.
  16. *
  17. * In this implementation, session objects are only visible to the session
  18. * that created or generated them.
  19. */
  20. #include "seccomon.h"
  21. #include "secitem.h"
  22. #include "pkcs11.h"
  23. #include "pkcs11i.h"
  24. #include "softoken.h"
  25. #include "lowkeyi.h"
  26. #include "blapi.h"
  27. #include "secder.h"
  28. #include "secport.h"
  29. #include "secrng.h"
  30. #include "prtypes.h"
  31. #include "nspr.h"
  32. #include "softkver.h"
  33. #include "secoid.h"
  34. #include "sftkdb.h"
  35. #include "utilpars.h"
  36. #include "ec.h"
  37. #include "secasn1.h"
  38. #include "secerr.h"
  39. #include "lgglue.h"
  40. PRBool parentForkedAfterC_Initialize;
  41. #ifndef NO_FORK_CHECK
  42. PRBool sftkForkCheckDisabled;
  43. #if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
  44. PRBool forked = PR_FALSE;
  45. #endif
  46. #if defined(CHECK_FORK_GETPID) || defined(CHECK_FORK_MIXED)
  47. #include <unistd.h>
  48. pid_t myPid;
  49. #endif
  50. #ifdef CHECK_FORK_MIXED
  51. #include <sys/systeminfo.h>
  52. PRBool usePthread_atfork;
  53. #endif
  54. #endif
  55. /*
  56. * ******************** Static data *******************************
  57. */
  58. /* The next three strings must be exactly 32 characters long */
  59. static char *manufacturerID = "Mozilla Foundation ";
  60. static char manufacturerID_space[33];
  61. static char *libraryDescription = "NSS Internal Crypto Services ";
  62. static char libraryDescription_space[33];
  63. /*
  64. * In FIPS mode, we disallow login attempts for 1 second after a login
  65. * failure so that there are at most 60 login attempts per minute.
  66. */
  67. static PRIntervalTime loginWaitTime;
  68. static PRUint32 minSessionObjectHandle = 1U;
  69. #define __PASTE(x, y) x##y
  70. /*
  71. * we renamed all our internal functions, get the correct
  72. * definitions for them...
  73. */
  74. #undef CK_PKCS11_FUNCTION_INFO
  75. #undef CK_NEED_ARG_LIST
  76. #define CK_PKCS11_3_0 1
  77. #define CK_EXTERN extern
  78. #define CK_PKCS11_FUNCTION_INFO(func) \
  79. CK_RV __PASTE(NS, func)
  80. #define CK_NEED_ARG_LIST 1
  81. #include "pkcs11f.h"
  82. /* build the crypto module table */
  83. static CK_FUNCTION_LIST_3_0 sftk_funcList = {
  84. { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
  85. #undef CK_PKCS11_FUNCTION_INFO
  86. #undef CK_NEED_ARG_LIST
  87. #define CK_PKCS11_FUNCTION_INFO(func) \
  88. __PASTE(NS, func) \
  89. ,
  90. #include "pkcs11f.h"
  91. };
  92. /* need a special version of get info for version 2 which returns the version
  93. * 2.4 version number */
  94. CK_RV NSC_GetInfoV2(CK_INFO_PTR pInfo);
  95. CK_RV NSC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
  96. CK_MECHANISM_INFO_PTR pInfo);
  97. /* build the crypto module table */
  98. static CK_FUNCTION_LIST sftk_funcList_v2 = {
  99. { 2, 40 },
  100. #undef CK_PKCS11_3_0
  101. #define CK_PKCS_11_2_0_ONLY 1
  102. #undef CK_PKCS11_FUNCTION_INFO
  103. #undef CK_NEED_ARG_LIST
  104. #define C_GetInfo C_GetInfoV2
  105. #define C_GetMechanismInfo C_GetMechanismInfoV2
  106. #define CK_PKCS11_FUNCTION_INFO(func) \
  107. __PASTE(NS, func) \
  108. ,
  109. #include "pkcs11f.h"
  110. };
  111. #undef C_GetInfo
  112. #undef C_GetMechanismInfo
  113. #undef CK_PKCS_11_2_0_ONLY
  114. #undef CK_PKCS11_FUNCTION_INFO
  115. #undef CK_NEED_ARG_LIST
  116. #undef __PASTE
  117. CK_NSS_MODULE_FUNCTIONS sftk_module_funcList = {
  118. { 1, 0 },
  119. NSC_ModuleDBFunc
  120. };
  121. /*
  122. * Array is orderd by default first
  123. */
  124. static CK_INTERFACE nss_interfaces[] = {
  125. { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_funcList, NSS_INTERFACE_FLAGS },
  126. { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_funcList_v2, NSS_INTERFACE_FLAGS },
  127. { (CK_UTF8CHAR_PTR) "Vendor NSS Module Interface", &sftk_module_funcList, NSS_INTERFACE_FLAGS }
  128. };
  129. /* must match the count of interfaces in nss_interfaces above */
  130. #define NSS_INTERFACE_COUNT 3
  131. /* List of DES Weak Keys */
  132. typedef unsigned char desKey[8];
  133. static const desKey sftk_desWeakTable[] = {
  134. #ifdef noParity
  135. /* weak */
  136. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  137. { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e },
  138. { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 },
  139. { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
  140. /* semi-weak */
  141. { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe },
  142. { 0xfe, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0xfe },
  143. { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 },
  144. { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
  145. { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x0f, 0x00, 0x0f },
  146. { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
  147. { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
  148. { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
  149. { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e },
  150. { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 },
  151. { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe },
  152. { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
  153. #else
  154. /* weak */
  155. { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
  156. { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e },
  157. { 0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1 },
  158. { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
  159. /* semi-weak */
  160. { 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe },
  161. { 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01 },
  162. { 0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1 },
  163. { 0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e },
  164. { 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1 },
  165. { 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01 },
  166. { 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
  167. { 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e },
  168. { 0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e },
  169. { 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01 },
  170. { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe },
  171. { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1 }
  172. #endif
  173. };
  174. static const int sftk_desWeakTableSize = sizeof(sftk_desWeakTable) /
  175. sizeof(sftk_desWeakTable[0]);
  176. /* DES KEY Parity conversion table. Takes each byte/2 as an index, returns
  177. * that byte with the proper parity bit set */
  178. static const unsigned char parityTable[256] = {
  179. /* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
  180. /* E */ 0x01, 0x02, 0x04, 0x07, 0x08, 0x0b, 0x0d, 0x0e,
  181. /* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
  182. /* O */ 0x10, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x1f,
  183. /* Odd....0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e */
  184. /* O */ 0x20, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x2f,
  185. /* Even...0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e */
  186. /* E */ 0x31, 0x32, 0x34, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
  187. /* Odd....0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e */
  188. /* O */ 0x40, 0x43, 0x45, 0x46, 0x49, 0x4a, 0x4c, 0x4f,
  189. /* Even...0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e */
  190. /* E */ 0x51, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, 0x5e,
  191. /* Even...0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e */
  192. /* E */ 0x61, 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x6e,
  193. /* Odd....0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e */
  194. /* O */ 0x70, 0x73, 0x75, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
  195. /* Odd....0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e */
  196. /* O */ 0x80, 0x83, 0x85, 0x86, 0x89, 0x8a, 0x8c, 0x8f,
  197. /* Even...0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e */
  198. /* E */ 0x91, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d, 0x9e,
  199. /* Even...0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae */
  200. /* E */ 0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xae,
  201. /* Odd....0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe */
  202. /* O */ 0xb0, 0xb3, 0xb5, 0xb6, 0xb9, 0xba, 0xbc, 0xbf,
  203. /* Even...0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce */
  204. /* E */ 0xc1, 0xc2, 0xc4, 0xc7, 0xc8, 0xcb, 0xcd, 0xce,
  205. /* Odd....0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde */
  206. /* O */ 0xd0, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc, 0xdf,
  207. /* Odd....0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee */
  208. /* O */ 0xe0, 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xef,
  209. /* Even...0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe */
  210. /* E */ 0xf1, 0xf2, 0xf4, 0xf7, 0xf8, 0xfb, 0xfd, 0xfe,
  211. };
  212. /* Mechanisms */
  213. struct mechanismList {
  214. CK_MECHANISM_TYPE type;
  215. CK_MECHANISM_INFO info;
  216. PRBool privkey;
  217. };
  218. /*
  219. * the following table includes a complete list of mechanism defined by
  220. * PKCS #11 version 2.01. Those Mechanisms not supported by this PKCS #11
  221. * module are ifdef'ed out.
  222. */
  223. #define CKF_EN_DE CKF_ENCRYPT | CKF_DECRYPT
  224. #define CKF_WR_UN CKF_WRAP | CKF_UNWRAP
  225. #define CKF_SN_VR CKF_SIGN | CKF_VERIFY
  226. #define CKF_SN_RE CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER
  227. #define CKF_EN_DE_MSG CKF_ENCRYPT | CKF_DECRYPT | CKF_MESSAGE_ENCRYPT | CKF_MESSAGE_DECRYPT
  228. #define CKF_EN_DE_WR_UN CKF_EN_DE | CKF_WR_UN
  229. #define CKF_SN_VR_RE CKF_SN_VR | CKF_SN_RE
  230. #define CKF_DUZ_IT_ALL CKF_EN_DE_WR_UN | CKF_SN_VR_RE
  231. #define CKF_EC_PNU CKF_EC_F_P | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS
  232. #define CKF_EC_BPNU CKF_EC_F_2M | CKF_EC_PNU
  233. #define CK_MAX 0xffffffff
  234. static const struct mechanismList mechanisms[] = {
  235. /*
  236. * PKCS #11 Mechanism List.
  237. *
  238. * The first argument is the PKCS #11 Mechanism we support.
  239. * The second argument is Mechanism info structure. It includes:
  240. * The minimum key size,
  241. * in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
  242. * in bytes for RC5, AES, Camellia, and CAST*
  243. * ignored for DES*, IDEA and FORTEZZA based
  244. * The maximum key size,
  245. * in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
  246. * in bytes for RC5, AES, Camellia, and CAST*
  247. * ignored for DES*, IDEA and FORTEZZA based
  248. * Flags
  249. * What operations are supported by this mechanism.
  250. * The third argument is a bool which tells if this mechanism is
  251. * supported in the database token.
  252. *
  253. */
  254. /* ------------------------- RSA Operations ---------------------------*/
  255. { CKM_RSA_PKCS_KEY_PAIR_GEN, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_GENERATE_KEY_PAIR }, PR_TRUE },
  256. { CKM_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_DUZ_IT_ALL }, PR_TRUE },
  257. { CKM_RSA_PKCS_PSS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
  258. { CKM_RSA_PKCS_OAEP, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_EN_DE_WR_UN }, PR_TRUE },
  259. #ifdef SFTK_RSA9796_SUPPORTED
  260. { CKM_RSA_9796, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_DUZ_IT_ALL }, PR_TRUE },
  261. #endif
  262. { CKM_RSA_X_509, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_DUZ_IT_ALL }, PR_TRUE },
  263. /* -------------- RSA Multipart Signing Operations -------------------- */
  264. { CKM_MD2_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
  265. { CKM_MD5_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
  266. { CKM_SHA1_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
  267. { CKM_SHA224_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
  268. { CKM_SHA256_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
  269. { CKM_SHA384_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
  270. { CKM_SHA512_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
  271. /* ------------------------- DSA Operations --------------------------- */
  272. { CKM_DSA_KEY_PAIR_GEN, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_GENERATE_KEY_PAIR }, PR_TRUE },
  273. { CKM_DSA, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_SN_VR }, PR_TRUE },
  274. { CKM_DSA_PARAMETER_GEN, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_GENERATE }, PR_TRUE },
  275. { CKM_DSA_SHA1, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_SN_VR }, PR_TRUE },
  276. { CKM_DSA_SHA224, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_SN_VR }, PR_TRUE },
  277. { CKM_DSA_SHA256, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_SN_VR }, PR_TRUE },
  278. { CKM_DSA_SHA384, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_SN_VR }, PR_TRUE },
  279. { CKM_DSA_SHA512, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_SN_VR }, PR_TRUE },
  280. /* -------------------- Diffie Hellman Operations --------------------- */
  281. /* no diffie hellman yet */
  282. { CKM_DH_PKCS_KEY_PAIR_GEN, { DH_MIN_P_BITS, DH_MAX_P_BITS, CKF_GENERATE_KEY_PAIR }, PR_TRUE },
  283. { CKM_DH_PKCS_DERIVE, { DH_MIN_P_BITS, DH_MAX_P_BITS, CKF_DERIVE }, PR_TRUE },
  284. /* -------------------- Elliptic Curve Operations --------------------- */
  285. { CKM_EC_KEY_PAIR_GEN, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_GENERATE_KEY_PAIR | CKF_EC_BPNU }, PR_TRUE },
  286. { CKM_ECDH1_DERIVE, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_DERIVE | CKF_EC_BPNU }, PR_TRUE },
  287. { CKM_ECDSA, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
  288. { CKM_ECDSA_SHA1, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
  289. { CKM_ECDSA_SHA224, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
  290. { CKM_ECDSA_SHA256, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
  291. { CKM_ECDSA_SHA384, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
  292. { CKM_ECDSA_SHA512, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
  293. /* ------------------------- RC2 Operations --------------------------- */
  294. { CKM_RC2_KEY_GEN, { 1, 128, CKF_GENERATE }, PR_TRUE },
  295. { CKM_RC2_ECB, { 1, 128, CKF_EN_DE_WR_UN }, PR_TRUE },
  296. { CKM_RC2_CBC, { 1, 128, CKF_EN_DE_WR_UN }, PR_TRUE },
  297. { CKM_RC2_MAC, { 1, 128, CKF_SN_VR }, PR_TRUE },
  298. { CKM_RC2_MAC_GENERAL, { 1, 128, CKF_SN_VR }, PR_TRUE },
  299. { CKM_RC2_CBC_PAD, { 1, 128, CKF_EN_DE_WR_UN }, PR_TRUE },
  300. /* ------------------------- RC4 Operations --------------------------- */
  301. { CKM_RC4_KEY_GEN, { 1, 256, CKF_GENERATE }, PR_FALSE },
  302. { CKM_RC4, { 1, 256, CKF_EN_DE_WR_UN }, PR_FALSE },
  303. /* ------------------------- DES Operations --------------------------- */
  304. { CKM_DES_KEY_GEN, { 8, 8, CKF_GENERATE }, PR_TRUE },
  305. { CKM_DES_ECB, { 8, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  306. { CKM_DES_CBC, { 8, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  307. { CKM_DES_MAC, { 8, 8, CKF_SN_VR }, PR_TRUE },
  308. { CKM_DES_MAC_GENERAL, { 8, 8, CKF_SN_VR }, PR_TRUE },
  309. { CKM_DES_CBC_PAD, { 8, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  310. { CKM_DES2_KEY_GEN, { 24, 24, CKF_GENERATE }, PR_TRUE },
  311. { CKM_DES3_KEY_GEN, { 24, 24, CKF_GENERATE }, PR_TRUE },
  312. { CKM_DES3_ECB, { 24, 24, CKF_EN_DE_WR_UN }, PR_TRUE },
  313. { CKM_DES3_CBC, { 24, 24, CKF_EN_DE_WR_UN }, PR_TRUE },
  314. { CKM_DES3_MAC, { 24, 24, CKF_SN_VR }, PR_TRUE },
  315. { CKM_DES3_MAC_GENERAL, { 24, 24, CKF_SN_VR }, PR_TRUE },
  316. { CKM_DES3_CBC_PAD, { 24, 24, CKF_EN_DE_WR_UN }, PR_TRUE },
  317. /* ------------------------- CDMF Operations --------------------------- */
  318. { CKM_CDMF_KEY_GEN, { 8, 8, CKF_GENERATE }, PR_TRUE },
  319. { CKM_CDMF_ECB, { 8, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  320. { CKM_CDMF_CBC, { 8, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  321. { CKM_CDMF_MAC, { 8, 8, CKF_SN_VR }, PR_TRUE },
  322. { CKM_CDMF_MAC_GENERAL, { 8, 8, CKF_SN_VR }, PR_TRUE },
  323. { CKM_CDMF_CBC_PAD, { 8, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  324. /* ------------------------- AES Operations --------------------------- */
  325. { CKM_AES_KEY_GEN, { 16, 32, CKF_GENERATE }, PR_TRUE },
  326. { CKM_AES_ECB, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  327. { CKM_AES_CBC, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  328. { CKM_AES_MAC, { 16, 32, CKF_SN_VR }, PR_TRUE },
  329. { CKM_AES_MAC_GENERAL, { 16, 32, CKF_SN_VR }, PR_TRUE },
  330. { CKM_AES_CMAC, { 16, 32, CKF_SN_VR }, PR_TRUE },
  331. { CKM_AES_CMAC_GENERAL, { 16, 32, CKF_SN_VR }, PR_TRUE },
  332. { CKM_AES_CBC_PAD, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  333. { CKM_AES_CTS, { 16, 32, CKF_EN_DE }, PR_TRUE },
  334. { CKM_AES_CTR, { 16, 32, CKF_EN_DE }, PR_TRUE },
  335. { CKM_AES_GCM, { 16, 32, CKF_EN_DE_MSG }, PR_TRUE },
  336. { CKM_AES_XCBC_MAC_96, { 12, 12, CKF_SN_VR }, PR_TRUE },
  337. { CKM_AES_XCBC_MAC, { 16, 16, CKF_SN_VR }, PR_TRUE },
  338. /* ------------------------- Camellia Operations --------------------- */
  339. { CKM_CAMELLIA_KEY_GEN, { 16, 32, CKF_GENERATE }, PR_TRUE },
  340. { CKM_CAMELLIA_ECB, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  341. { CKM_CAMELLIA_CBC, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  342. { CKM_CAMELLIA_MAC, { 16, 32, CKF_SN_VR }, PR_TRUE },
  343. { CKM_CAMELLIA_MAC_GENERAL, { 16, 32, CKF_SN_VR }, PR_TRUE },
  344. { CKM_CAMELLIA_CBC_PAD, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  345. /* ------------------------- SEED Operations --------------------------- */
  346. { CKM_SEED_KEY_GEN, { 16, 16, CKF_GENERATE }, PR_TRUE },
  347. { CKM_SEED_ECB, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  348. { CKM_SEED_CBC, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  349. { CKM_SEED_MAC, { 16, 16, CKF_SN_VR }, PR_TRUE },
  350. { CKM_SEED_MAC_GENERAL, { 16, 16, CKF_SN_VR }, PR_TRUE },
  351. { CKM_SEED_CBC_PAD, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  352. #ifndef NSS_DISABLE_CHACHAPOLY
  353. /* ------------------------- ChaCha20 Operations ---------------------- */
  354. { CKM_NSS_CHACHA20_KEY_GEN, { 32, 32, CKF_GENERATE }, PR_TRUE },
  355. { CKM_NSS_CHACHA20_POLY1305, { 32, 32, CKF_EN_DE }, PR_TRUE },
  356. { CKM_NSS_CHACHA20_CTR, { 32, 32, CKF_EN_DE }, PR_TRUE },
  357. { CKM_CHACHA20_KEY_GEN, { 32, 32, CKF_GENERATE }, PR_TRUE },
  358. { CKM_CHACHA20_POLY1305, { 32, 32, CKF_EN_DE_MSG }, PR_TRUE },
  359. #endif /* NSS_DISABLE_CHACHAPOLY */
  360. /* ------------------------- Hashing Operations ----------------------- */
  361. { CKM_MD2, { 0, 0, CKF_DIGEST }, PR_FALSE },
  362. { CKM_MD2_HMAC, { 1, 128, CKF_SN_VR }, PR_TRUE },
  363. { CKM_MD2_HMAC_GENERAL, { 1, 128, CKF_SN_VR }, PR_TRUE },
  364. { CKM_MD5, { 0, 0, CKF_DIGEST }, PR_FALSE },
  365. { CKM_MD5_HMAC, { 1, 128, CKF_SN_VR }, PR_TRUE },
  366. { CKM_MD5_HMAC_GENERAL, { 1, 128, CKF_SN_VR }, PR_TRUE },
  367. { CKM_SHA_1, { 0, 0, CKF_DIGEST }, PR_FALSE },
  368. { CKM_SHA_1_HMAC, { 1, 128, CKF_SN_VR }, PR_TRUE },
  369. { CKM_SHA_1_HMAC_GENERAL, { 1, 128, CKF_SN_VR }, PR_TRUE },
  370. { CKM_SHA224, { 0, 0, CKF_DIGEST }, PR_FALSE },
  371. { CKM_SHA224_HMAC, { 1, 128, CKF_SN_VR }, PR_TRUE },
  372. { CKM_SHA224_HMAC_GENERAL, { 1, 128, CKF_SN_VR }, PR_TRUE },
  373. { CKM_SHA256, { 0, 0, CKF_DIGEST }, PR_FALSE },
  374. { CKM_SHA256_HMAC, { 1, 128, CKF_SN_VR }, PR_TRUE },
  375. { CKM_SHA256_HMAC_GENERAL, { 1, 128, CKF_SN_VR }, PR_TRUE },
  376. { CKM_SHA384, { 0, 0, CKF_DIGEST }, PR_FALSE },
  377. { CKM_SHA384_HMAC, { 1, 128, CKF_SN_VR }, PR_TRUE },
  378. { CKM_SHA384_HMAC_GENERAL, { 1, 128, CKF_SN_VR }, PR_TRUE },
  379. { CKM_SHA512, { 0, 0, CKF_DIGEST }, PR_FALSE },
  380. { CKM_SHA512_HMAC, { 1, 128, CKF_SN_VR }, PR_TRUE },
  381. { CKM_SHA512_HMAC_GENERAL, { 1, 128, CKF_SN_VR }, PR_TRUE },
  382. { CKM_TLS_PRF_GENERAL, { 0, 512, CKF_SN_VR }, PR_FALSE },
  383. { CKM_TLS_MAC, { 0, 512, CKF_SN_VR }, PR_FALSE },
  384. { CKM_NSS_TLS_PRF_GENERAL_SHA256,
  385. { 0, 512, CKF_SN_VR },
  386. PR_FALSE },
  387. /* ------------------------- HKDF Operations -------------------------- */
  388. { CKM_HKDF_DERIVE, { 1, 255 * 64, CKF_DERIVE }, PR_TRUE },
  389. { CKM_HKDF_DATA, { 1, 255 * 64, CKF_DERIVE }, PR_TRUE },
  390. { CKM_HKDF_KEY_GEN, { 20, 64, CKF_GENERATE }, PR_TRUE },
  391. { CKM_NSS_HKDF_SHA1, { 1, 128, CKF_DERIVE }, PR_TRUE },
  392. { CKM_NSS_HKDF_SHA256, { 1, 128, CKF_DERIVE }, PR_TRUE },
  393. { CKM_NSS_HKDF_SHA384, { 1, 128, CKF_DERIVE }, PR_TRUE },
  394. { CKM_NSS_HKDF_SHA512, { 1, 128, CKF_DERIVE }, PR_TRUE },
  395. /* ------------------------- CAST Operations --------------------------- */
  396. #ifdef NSS_SOFTOKEN_DOES_CAST
  397. /* Cast operations are not supported ( yet? ) */
  398. { CKM_CAST_KEY_GEN, { 1, 8, CKF_GENERATE }, PR_TRUE },
  399. { CKM_CAST_ECB, { 1, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  400. { CKM_CAST_CBC, { 1, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  401. { CKM_CAST_MAC, { 1, 8, CKF_SN_VR }, PR_TRUE },
  402. { CKM_CAST_MAC_GENERAL, { 1, 8, CKF_SN_VR }, PR_TRUE },
  403. { CKM_CAST_CBC_PAD, { 1, 8, CKF_EN_DE_WR_UN }, PR_TRUE },
  404. { CKM_CAST3_KEY_GEN, { 1, 16, CKF_GENERATE }, PR_TRUE },
  405. { CKM_CAST3_ECB, { 1, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  406. { CKM_CAST3_CBC, { 1, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  407. { CKM_CAST3_MAC, { 1, 16, CKF_SN_VR }, PR_TRUE },
  408. { CKM_CAST3_MAC_GENERAL, { 1, 16, CKF_SN_VR }, PR_TRUE },
  409. { CKM_CAST3_CBC_PAD, { 1, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  410. { CKM_CAST5_KEY_GEN, { 1, 16, CKF_GENERATE }, PR_TRUE },
  411. { CKM_CAST5_ECB, { 1, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  412. { CKM_CAST5_CBC, { 1, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  413. { CKM_CAST5_MAC, { 1, 16, CKF_SN_VR }, PR_TRUE },
  414. { CKM_CAST5_MAC_GENERAL, { 1, 16, CKF_SN_VR }, PR_TRUE },
  415. { CKM_CAST5_CBC_PAD, { 1, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  416. #endif
  417. #if NSS_SOFTOKEN_DOES_RC5
  418. /* ------------------------- RC5 Operations --------------------------- */
  419. { CKM_RC5_KEY_GEN, { 1, 32, CKF_GENERATE }, PR_TRUE },
  420. { CKM_RC5_ECB, { 1, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  421. { CKM_RC5_CBC, { 1, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  422. { CKM_RC5_MAC, { 1, 32, CKF_SN_VR }, PR_TRUE },
  423. { CKM_RC5_MAC_GENERAL, { 1, 32, CKF_SN_VR }, PR_TRUE },
  424. { CKM_RC5_CBC_PAD, { 1, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  425. #endif
  426. #ifdef NSS_SOFTOKEN_DOES_IDEA
  427. /* ------------------------- IDEA Operations -------------------------- */
  428. { CKM_IDEA_KEY_GEN, { 16, 16, CKF_GENERATE }, PR_TRUE },
  429. { CKM_IDEA_ECB, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  430. { CKM_IDEA_CBC, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  431. { CKM_IDEA_MAC, { 16, 16, CKF_SN_VR }, PR_TRUE },
  432. { CKM_IDEA_MAC_GENERAL, { 16, 16, CKF_SN_VR }, PR_TRUE },
  433. { CKM_IDEA_CBC_PAD, { 16, 16, CKF_EN_DE_WR_UN }, PR_TRUE },
  434. #endif
  435. /* --------------------- Secret Key Operations ------------------------ */
  436. { CKM_GENERIC_SECRET_KEY_GEN, { 1, 32, CKF_GENERATE }, PR_TRUE },
  437. { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE },
  438. { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  439. { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_DERIVE }, PR_FALSE },
  440. { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  441. { CKM_EXTRACT_KEY_FROM_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE },
  442. { CKM_DES3_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  443. { CKM_DES3_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  444. { CKM_AES_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  445. { CKM_AES_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  446. { CKM_CAMELLIA_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  447. { CKM_CAMELLIA_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  448. { CKM_SEED_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  449. { CKM_SEED_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE },
  450. /* ---------------------- SSL Key Derivations ------------------------- */
  451. { CKM_SSL3_PRE_MASTER_KEY_GEN, { 48, 48, CKF_GENERATE }, PR_FALSE },
  452. { CKM_SSL3_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
  453. { CKM_SSL3_MASTER_KEY_DERIVE_DH, { 8, 128, CKF_DERIVE }, PR_FALSE },
  454. { CKM_SSL3_KEY_AND_MAC_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
  455. { CKM_SSL3_MD5_MAC, { 0, 16, CKF_DERIVE }, PR_FALSE },
  456. { CKM_SSL3_SHA1_MAC, { 0, 20, CKF_DERIVE }, PR_FALSE },
  457. { CKM_MD5_KEY_DERIVATION, { 0, 16, CKF_DERIVE }, PR_FALSE },
  458. { CKM_MD2_KEY_DERIVATION, { 0, 16, CKF_DERIVE }, PR_FALSE },
  459. { CKM_SHA1_KEY_DERIVATION, { 0, 20, CKF_DERIVE }, PR_FALSE },
  460. { CKM_SHA224_KEY_DERIVATION, { 0, 28, CKF_DERIVE }, PR_FALSE },
  461. { CKM_SHA256_KEY_DERIVATION, { 0, 32, CKF_DERIVE }, PR_FALSE },
  462. { CKM_SHA384_KEY_DERIVATION, { 0, 48, CKF_DERIVE }, PR_FALSE },
  463. { CKM_SHA512_KEY_DERIVATION, { 0, 64, CKF_DERIVE }, PR_FALSE },
  464. { CKM_TLS_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
  465. { CKM_TLS12_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
  466. { CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256,
  467. { 48, 48, CKF_DERIVE },
  468. PR_FALSE },
  469. { CKM_TLS_MASTER_KEY_DERIVE_DH, { 8, 128, CKF_DERIVE }, PR_FALSE },
  470. { CKM_TLS12_MASTER_KEY_DERIVE_DH, { 8, 128, CKF_DERIVE }, PR_FALSE },
  471. { CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256,
  472. { 8, 128, CKF_DERIVE },
  473. PR_FALSE },
  474. { CKM_TLS_KEY_AND_MAC_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
  475. { CKM_TLS12_KEY_AND_MAC_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
  476. { CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256,
  477. { 48, 48, CKF_DERIVE },
  478. PR_FALSE },
  479. { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE,
  480. { 48, 128, CKF_DERIVE },
  481. PR_FALSE },
  482. { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH,
  483. { 48, 128, CKF_DERIVE },
  484. PR_FALSE },
  485. /* ---------------------- PBE Key Derivations ------------------------ */
  486. { CKM_PBE_MD2_DES_CBC, { 8, 8, CKF_DERIVE }, PR_TRUE },
  487. { CKM_PBE_MD5_DES_CBC, { 8, 8, CKF_DERIVE }, PR_TRUE },
  488. /* ------------------ NSS PBE Key Derivations ------------------- */
  489. { CKM_NSS_PBE_SHA1_DES_CBC, { 8, 8, CKF_GENERATE }, PR_TRUE },
  490. { CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC, { 24, 24, CKF_GENERATE }, PR_TRUE },
  491. { CKM_PBE_SHA1_DES3_EDE_CBC, { 24, 24, CKF_GENERATE }, PR_TRUE },
  492. { CKM_PBE_SHA1_DES2_EDE_CBC, { 24, 24, CKF_GENERATE }, PR_TRUE },
  493. { CKM_PBE_SHA1_RC2_40_CBC, { 40, 40, CKF_GENERATE }, PR_TRUE },
  494. { CKM_PBE_SHA1_RC2_128_CBC, { 128, 128, CKF_GENERATE }, PR_TRUE },
  495. { CKM_PBE_SHA1_RC4_40, { 40, 40, CKF_GENERATE }, PR_TRUE },
  496. { CKM_PBE_SHA1_RC4_128, { 128, 128, CKF_GENERATE }, PR_TRUE },
  497. { CKM_PBA_SHA1_WITH_SHA1_HMAC, { 20, 20, CKF_GENERATE }, PR_TRUE },
  498. { CKM_PKCS5_PBKD2, { 1, 256, CKF_GENERATE }, PR_TRUE },
  499. { CKM_NSS_PBE_SHA1_HMAC_KEY_GEN, { 20, 20, CKF_GENERATE }, PR_TRUE },
  500. { CKM_NSS_PBE_MD5_HMAC_KEY_GEN, { 16, 16, CKF_GENERATE }, PR_TRUE },
  501. { CKM_NSS_PBE_MD2_HMAC_KEY_GEN, { 16, 16, CKF_GENERATE }, PR_TRUE },
  502. { CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN, { 28, 28, CKF_GENERATE }, PR_TRUE },
  503. { CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN, { 32, 32, CKF_GENERATE }, PR_TRUE },
  504. { CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN, { 48, 48, CKF_GENERATE }, PR_TRUE },
  505. { CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, { 64, 64, CKF_GENERATE }, PR_TRUE },
  506. /* ------------------ NIST 800-108 Key Derivations ------------------- */
  507. { CKM_SP800_108_COUNTER_KDF, { 0, CK_MAX, CKF_DERIVE }, PR_TRUE },
  508. { CKM_SP800_108_FEEDBACK_KDF, { 0, CK_MAX, CKF_DERIVE }, PR_TRUE },
  509. { CKM_SP800_108_DOUBLE_PIPELINE_KDF, { 0, CK_MAX, CKF_DERIVE }, PR_TRUE },
  510. { CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_DERIVE }, PR_TRUE },
  511. { CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_DERIVE }, PR_TRUE },
  512. { CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA, { 0, CK_MAX, CKF_DERIVE }, PR_TRUE },
  513. /* ------------------ AES Key Wrap (also encrypt) ------------------- */
  514. { CKM_NSS_AES_KEY_WRAP, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  515. { CKM_NSS_AES_KEY_WRAP_PAD, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  516. { CKM_AES_KEY_WRAP, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  517. { CKM_AES_KEY_WRAP_PAD, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  518. { CKM_AES_KEY_WRAP_KWP, { 1, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
  519. /* --------------------------- J-PAKE -------------------------------- */
  520. { CKM_NSS_JPAKE_ROUND1_SHA1, { 0, 0, CKF_GENERATE }, PR_TRUE },
  521. { CKM_NSS_JPAKE_ROUND1_SHA256, { 0, 0, CKF_GENERATE }, PR_TRUE },
  522. { CKM_NSS_JPAKE_ROUND1_SHA384, { 0, 0, CKF_GENERATE }, PR_TRUE },
  523. { CKM_NSS_JPAKE_ROUND1_SHA512, { 0, 0, CKF_GENERATE }, PR_TRUE },
  524. { CKM_NSS_JPAKE_ROUND2_SHA1, { 0, 0, CKF_DERIVE }, PR_TRUE },
  525. { CKM_NSS_JPAKE_ROUND2_SHA256, { 0, 0, CKF_DERIVE }, PR_TRUE },
  526. { CKM_NSS_JPAKE_ROUND2_SHA384, { 0, 0, CKF_DERIVE }, PR_TRUE },
  527. { CKM_NSS_JPAKE_ROUND2_SHA512, { 0, 0, CKF_DERIVE }, PR_TRUE },
  528. { CKM_NSS_JPAKE_FINAL_SHA1, { 0, 0, CKF_DERIVE }, PR_TRUE },
  529. { CKM_NSS_JPAKE_FINAL_SHA256, { 0, 0, CKF_DERIVE }, PR_TRUE },
  530. { CKM_NSS_JPAKE_FINAL_SHA384, { 0, 0, CKF_DERIVE }, PR_TRUE },
  531. { CKM_NSS_JPAKE_FINAL_SHA512, { 0, 0, CKF_DERIVE }, PR_TRUE },
  532. /* -------------------- Constant Time TLS MACs ----------------------- */
  533. { CKM_NSS_HMAC_CONSTANT_TIME, { 0, 0, CKF_DIGEST }, PR_TRUE },
  534. { CKM_NSS_SSL3_MAC_CONSTANT_TIME, { 0, 0, CKF_DIGEST }, PR_TRUE },
  535. /* --------------------IPSEC ----------------------- */
  536. { CKM_NSS_IKE_PRF_PLUS_DERIVE, { 8, 255 * 64, CKF_DERIVE }, PR_TRUE },
  537. { CKM_NSS_IKE_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE },
  538. { CKM_NSS_IKE1_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE },
  539. { CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 8, 255 * 64, CKF_DERIVE }, PR_TRUE }
  540. };
  541. static const CK_ULONG mechanismCount = sizeof(mechanisms) / sizeof(mechanisms[0]);
  542. /* sigh global so fipstokn can read it */
  543. PRBool nsc_init = PR_FALSE;
  544. #if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
  545. #include <pthread.h>
  546. static void
  547. ForkedChild(void)
  548. {
  549. if (nsc_init || nsf_init) {
  550. forked = PR_TRUE;
  551. }
  552. }
  553. #endif
  554. static char *
  555. sftk_setStringName(const char *inString, char *buffer, int buffer_length, PRBool nullTerminate)
  556. {
  557. int full_length, string_length;
  558. full_length = nullTerminate ? buffer_length - 1 : buffer_length;
  559. string_length = PORT_Strlen(inString);
  560. /*
  561. * shorten the string, respecting utf8 encoding
  562. * to do so, we work backward from the end
  563. * bytes looking from the end are either:
  564. * - ascii [0x00,0x7f]
  565. * - the [2-n]th byte of a multibyte sequence
  566. * [0x3F,0xBF], i.e, most significant 2 bits are '10'
  567. * - the first byte of a multibyte sequence [0xC0,0xFD],
  568. * i.e, most significant 2 bits are '11'
  569. *
  570. * When the string is too long, we lop off any trailing '10' bytes,
  571. * if any. When these are all eliminated we lop off
  572. * one additional byte. Thus if we lopped any '10'
  573. * we'll be lopping a '11' byte (the first byte of the multibyte sequence),
  574. * otherwise we're lopping off an ascii character.
  575. *
  576. * To test for '10' bytes, we first AND it with
  577. * 11000000 (0xc0) so that we get 10000000 (0x80) if and only if
  578. * the byte starts with 10. We test for equality.
  579. */
  580. while (string_length > full_length) {
  581. /* need to shorten */
  582. while (string_length > 0 &&
  583. ((inString[string_length - 1] & (char)0xc0) == (char)0x80)) {
  584. /* lop off '10' byte */
  585. string_length--;
  586. }
  587. /*
  588. * test string_length in case bad data is received
  589. * and string consisted of all '10' bytes,
  590. * avoiding any infinite loop
  591. */
  592. if (string_length) {
  593. /* remove either '11' byte or an asci byte */
  594. string_length--;
  595. }
  596. }
  597. PORT_Memset(buffer, ' ', full_length);
  598. if (nullTerminate) {
  599. buffer[full_length] = 0;
  600. }
  601. PORT_Memcpy(buffer, inString, string_length);
  602. return buffer;
  603. }
  604. /*
  605. * Configuration utils
  606. */
  607. static CK_RV
  608. sftk_configure(const char *man, const char *libdes)
  609. {
  610. /* make sure the internationalization was done correctly... */
  611. if (man) {
  612. manufacturerID = sftk_setStringName(man, manufacturerID_space,
  613. sizeof(manufacturerID_space), PR_TRUE);
  614. }
  615. if (libdes) {
  616. libraryDescription = sftk_setStringName(libdes,
  617. libraryDescription_space, sizeof(libraryDescription_space),
  618. PR_TRUE);
  619. }
  620. return CKR_OK;
  621. }
  622. /*
  623. * ******************** Password Utilities *******************************
  624. */
  625. /*
  626. * see if the key DB password is enabled
  627. */
  628. static PRBool
  629. sftk_hasNullPassword(SFTKSlot *slot, SFTKDBHandle *keydb)
  630. {
  631. PRBool pwenabled;
  632. pwenabled = PR_FALSE;
  633. if (sftkdb_HasPasswordSet(keydb) == SECSuccess) {
  634. PRBool tokenRemoved = PR_FALSE;
  635. SECStatus rv = sftkdb_CheckPasswordNull(keydb, &tokenRemoved);
  636. if (tokenRemoved) {
  637. sftk_CloseAllSessions(slot, PR_FALSE);
  638. }
  639. return (rv == SECSuccess);
  640. }
  641. return pwenabled;
  642. }
  643. /*
  644. * ******************** Object Creation Utilities ***************************
  645. */
  646. /* Make sure a given attribute exists. If it doesn't, initialize it to
  647. * value and len
  648. */
  649. CK_RV
  650. sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
  651. const void *value, unsigned int len)
  652. {
  653. if (!sftk_hasAttribute(object, type)) {
  654. return sftk_AddAttributeType(object, type, value, len);
  655. }
  656. return CKR_OK;
  657. }
  658. /*
  659. * check the consistancy and initialize a Data Object
  660. */
  661. static CK_RV
  662. sftk_handleDataObject(SFTKSession *session, SFTKObject *object)
  663. {
  664. CK_RV crv;
  665. /* first reject private and token data objects */
  666. if (sftk_isTrue(object, CKA_PRIVATE) || sftk_isTrue(object, CKA_TOKEN)) {
  667. return CKR_ATTRIBUTE_VALUE_INVALID;
  668. }
  669. /* now just verify the required date fields */
  670. crv = sftk_defaultAttribute(object, CKA_APPLICATION, NULL, 0);
  671. if (crv != CKR_OK)
  672. return crv;
  673. crv = sftk_defaultAttribute(object, CKA_VALUE, NULL, 0);
  674. if (crv != CKR_OK)
  675. return crv;
  676. return CKR_OK;
  677. }
  678. /*
  679. * check the consistancy and initialize a Certificate Object
  680. */
  681. static CK_RV
  682. sftk_handleCertObject(SFTKSession *session, SFTKObject *object)
  683. {
  684. CK_CERTIFICATE_TYPE type;
  685. SFTKAttribute *attribute;
  686. CK_RV crv;
  687. /* certificates must have a type */
  688. if (!sftk_hasAttribute(object, CKA_CERTIFICATE_TYPE)) {
  689. return CKR_TEMPLATE_INCOMPLETE;
  690. }
  691. /* we can't store any certs private */
  692. if (sftk_isTrue(object, CKA_PRIVATE)) {
  693. return CKR_ATTRIBUTE_VALUE_INVALID;
  694. }
  695. /* We only support X.509 Certs for now */
  696. attribute = sftk_FindAttribute(object, CKA_CERTIFICATE_TYPE);
  697. if (attribute == NULL)
  698. return CKR_TEMPLATE_INCOMPLETE;
  699. type = *(CK_CERTIFICATE_TYPE *)attribute->attrib.pValue;
  700. sftk_FreeAttribute(attribute);
  701. if (type != CKC_X_509) {
  702. return CKR_ATTRIBUTE_VALUE_INVALID;
  703. }
  704. /* X.509 Certificate */
  705. /* make sure we have a cert */
  706. if (!sftk_hasAttribute(object, CKA_VALUE)) {
  707. return CKR_TEMPLATE_INCOMPLETE;
  708. }
  709. /* in PKCS #11, Subject is a required field */
  710. if (!sftk_hasAttribute(object, CKA_SUBJECT)) {
  711. return CKR_TEMPLATE_INCOMPLETE;
  712. }
  713. /* in PKCS #11, Issuer is a required field */
  714. if (!sftk_hasAttribute(object, CKA_ISSUER)) {
  715. return CKR_TEMPLATE_INCOMPLETE;
  716. }
  717. /* in PKCS #11, Serial is a required field */
  718. if (!sftk_hasAttribute(object, CKA_SERIAL_NUMBER)) {
  719. return CKR_TEMPLATE_INCOMPLETE;
  720. }
  721. /* add it to the object */
  722. object->objectInfo = NULL;
  723. object->infoFree = (SFTKFree)NULL;
  724. /* now just verify the required date fields */
  725. crv = sftk_defaultAttribute(object, CKA_ID, NULL, 0);
  726. if (crv != CKR_OK) {
  727. return crv;
  728. }
  729. if (sftk_isTrue(object, CKA_TOKEN)) {
  730. SFTKSlot *slot = session->slot;
  731. SFTKDBHandle *certHandle = sftk_getCertDB(slot);
  732. if (certHandle == NULL) {
  733. return CKR_TOKEN_WRITE_PROTECTED;
  734. }
  735. crv = sftkdb_write(certHandle, object, &object->handle);
  736. sftk_freeDB(certHandle);
  737. return crv;
  738. }
  739. return CKR_OK;
  740. }
  741. /*
  742. * check the consistancy and initialize a Trust Object
  743. */
  744. static CK_RV
  745. sftk_handleTrustObject(SFTKSession *session, SFTKObject *object)
  746. {
  747. /* we can't store any certs private */
  748. if (sftk_isTrue(object, CKA_PRIVATE)) {
  749. return CKR_ATTRIBUTE_VALUE_INVALID;
  750. }
  751. /* certificates must have a type */
  752. if (!sftk_hasAttribute(object, CKA_ISSUER)) {
  753. return CKR_TEMPLATE_INCOMPLETE;
  754. }
  755. if (!sftk_hasAttribute(object, CKA_SERIAL_NUMBER)) {
  756. return CKR_TEMPLATE_INCOMPLETE;
  757. }
  758. if (!sftk_hasAttribute(object, CKA_CERT_SHA1_HASH)) {
  759. return CKR_TEMPLATE_INCOMPLETE;
  760. }
  761. if (!sftk_hasAttribute(object, CKA_CERT_MD5_HASH)) {
  762. return CKR_TEMPLATE_INCOMPLETE;
  763. }
  764. if (sftk_isTrue(object, CKA_TOKEN)) {
  765. SFTKSlot *slot = session->slot;
  766. SFTKDBHandle *certHandle = sftk_getCertDB(slot);
  767. CK_RV crv;
  768. if (certHandle == NULL) {
  769. return CKR_TOKEN_WRITE_PROTECTED;
  770. }
  771. crv = sftkdb_write(certHandle, object, &object->handle);
  772. sftk_freeDB(certHandle);
  773. return crv;
  774. }
  775. return CKR_OK;
  776. }
  777. /*
  778. * check the consistancy and initialize a Trust Object
  779. */
  780. static CK_RV
  781. sftk_handleSMimeObject(SFTKSession *session, SFTKObject *object)
  782. {
  783. /* we can't store any certs private */
  784. if (sftk_isTrue(object, CKA_PRIVATE)) {
  785. return CKR_ATTRIBUTE_VALUE_INVALID;
  786. }
  787. /* certificates must have a type */
  788. if (!sftk_hasAttribute(object, CKA_SUBJECT)) {
  789. return CKR_TEMPLATE_INCOMPLETE;
  790. }
  791. if (!sftk_hasAttribute(object, CKA_NSS_EMAIL)) {
  792. return CKR_TEMPLATE_INCOMPLETE;
  793. }
  794. if (sftk_isTrue(object, CKA_TOKEN)) {
  795. SFTKSlot *slot = session->slot;
  796. SFTKDBHandle *certHandle;
  797. CK_RV crv;
  798. PORT_Assert(slot);
  799. if (slot == NULL) {
  800. return CKR_SESSION_HANDLE_INVALID;
  801. }
  802. certHandle = sftk_getCertDB(slot);
  803. if (certHandle == NULL) {
  804. return CKR_TOKEN_WRITE_PROTECTED;
  805. }
  806. crv = sftkdb_write(certHandle, object, &object->handle);
  807. sftk_freeDB(certHandle);
  808. return crv;
  809. }
  810. return CKR_OK;
  811. }
  812. /*
  813. * check the consistancy and initialize a Trust Object
  814. */
  815. static CK_RV
  816. sftk_handleCrlObject(SFTKSession *session, SFTKObject *object)
  817. {
  818. /* we can't store any certs private */
  819. if (sftk_isTrue(object, CKA_PRIVATE)) {
  820. return CKR_ATTRIBUTE_VALUE_INVALID;
  821. }
  822. /* certificates must have a type */
  823. if (!sftk_hasAttribute(object, CKA_SUBJECT)) {
  824. return CKR_TEMPLATE_INCOMPLETE;
  825. }
  826. if (!sftk_hasAttribute(object, CKA_VALUE)) {
  827. return CKR_TEMPLATE_INCOMPLETE;
  828. }
  829. if (sftk_isTrue(object, CKA_TOKEN)) {
  830. SFTKSlot *slot = session->slot;
  831. SFTKDBHandle *certHandle = sftk_getCertDB(slot);
  832. CK_RV crv;
  833. if (certHandle == NULL) {
  834. return CKR_TOKEN_WRITE_PROTECTED;
  835. }
  836. crv = sftkdb_write(certHandle, object, &object->handle);
  837. sftk_freeDB(certHandle);
  838. return crv;
  839. }
  840. return CKR_OK;
  841. }
  842. /*
  843. * check the consistancy and initialize a Public Key Object
  844. */
  845. static CK_RV
  846. sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
  847. CK_KEY_TYPE key_type)
  848. {
  849. CK_BBOOL encrypt = CK_TRUE;
  850. CK_BBOOL recover = CK_TRUE;
  851. CK_BBOOL wrap = CK_TRUE;
  852. CK_BBOOL derive = CK_FALSE;
  853. CK_BBOOL verify = CK_TRUE;
  854. CK_RV crv;
  855. switch (key_type) {
  856. case CKK_RSA:
  857. crv = sftk_ConstrainAttribute(object, CKA_MODULUS,
  858. RSA_MIN_MODULUS_BITS, 0, 0);
  859. if (crv != CKR_OK) {
  860. return crv;
  861. }
  862. crv = sftk_ConstrainAttribute(object, CKA_PUBLIC_EXPONENT, 2, 0, 0);
  863. if (crv != CKR_OK) {
  864. return crv;
  865. }
  866. break;
  867. case CKK_DSA:
  868. crv = sftk_ConstrainAttribute(object, CKA_SUBPRIME,
  869. DSA_MIN_Q_BITS, DSA_MAX_Q_BITS, 0);
  870. if (crv != CKR_OK) {
  871. return crv;
  872. }
  873. crv = sftk_ConstrainAttribute(object, CKA_PRIME,
  874. DSA_MIN_P_BITS, DSA_MAX_P_BITS, 64);
  875. if (crv != CKR_OK) {
  876. return crv;
  877. }
  878. crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DSA_MAX_P_BITS, 0);
  879. if (crv != CKR_OK) {
  880. return crv;
  881. }
  882. crv = sftk_ConstrainAttribute(object, CKA_VALUE, 2, DSA_MAX_P_BITS, 0);
  883. if (crv != CKR_OK) {
  884. return crv;
  885. }
  886. encrypt = CK_FALSE;
  887. recover = CK_FALSE;
  888. wrap = CK_FALSE;
  889. break;
  890. case CKK_DH:
  891. crv = sftk_ConstrainAttribute(object, CKA_PRIME,
  892. DH_MIN_P_BITS, DH_MAX_P_BITS, 0);
  893. if (crv != CKR_OK) {
  894. return crv;
  895. }
  896. crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DH_MAX_P_BITS, 0);
  897. if (crv != CKR_OK) {
  898. return crv;
  899. }
  900. crv = sftk_ConstrainAttribute(object, CKA_VALUE, 2, DH_MAX_P_BITS, 0);
  901. if (crv != CKR_OK) {
  902. return crv;
  903. }
  904. verify = CK_FALSE;
  905. derive = CK_TRUE;
  906. encrypt = CK_FALSE;
  907. recover = CK_FALSE;
  908. wrap = CK_FALSE;
  909. break;
  910. case CKK_EC:
  911. if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) {
  912. return CKR_TEMPLATE_INCOMPLETE;
  913. }
  914. if (!sftk_hasAttribute(object, CKA_EC_POINT)) {
  915. return CKR_TEMPLATE_INCOMPLETE;
  916. }
  917. derive = CK_TRUE; /* for ECDH */
  918. verify = CK_TRUE; /* for ECDSA */
  919. encrypt = CK_FALSE;
  920. recover = CK_FALSE;
  921. wrap = CK_FALSE;
  922. break;
  923. default:
  924. return CKR_ATTRIBUTE_VALUE_INVALID;
  925. }
  926. /* make sure the required fields exist */
  927. crv = sftk_defaultAttribute(object, CKA_SUBJECT, NULL, 0);
  928. if (crv != CKR_OK)
  929. return crv;
  930. crv = sftk_defaultAttribute(object, CKA_ENCRYPT, &encrypt, sizeof(CK_BBOOL));
  931. if (crv != CKR_OK)
  932. return crv;
  933. crv = sftk_defaultAttribute(object, CKA_VERIFY, &verify, sizeof(CK_BBOOL));
  934. if (crv != CKR_OK)
  935. return crv;
  936. crv = sftk_defaultAttribute(object, CKA_VERIFY_RECOVER,
  937. &recover, sizeof(CK_BBOOL));
  938. if (crv != CKR_OK)
  939. return crv;
  940. crv = sftk_defaultAttribute(object, CKA_WRAP, &wrap, sizeof(CK_BBOOL));
  941. if (crv != CKR_OK)
  942. return crv;
  943. crv = sftk_defaultAttribute(object, CKA_DERIVE, &derive, sizeof(CK_BBOOL));
  944. if (crv != CKR_OK)
  945. return crv;
  946. object->objectInfo = sftk_GetPubKey(object, key_type, &crv);
  947. if (object->objectInfo == NULL) {
  948. return crv;
  949. }
  950. object->infoFree = (SFTKFree)nsslowkey_DestroyPublicKey;
  951. /* Check that an imported EC key is valid */
  952. if (key_type == CKK_EC) {
  953. NSSLOWKEYPublicKey *pubKey = (NSSLOWKEYPublicKey *)object->objectInfo;
  954. SECStatus rv = EC_ValidatePublicKey(&pubKey->u.ec.ecParams,
  955. &pubKey->u.ec.publicValue);
  956. if (rv != SECSuccess) {
  957. return CKR_TEMPLATE_INCONSISTENT;
  958. }
  959. }
  960. if (sftk_isTrue(object, CKA_TOKEN)) {
  961. SFTKSlot *slot = session->slot;
  962. SFTKDBHandle *certHandle = sftk_getCertDB(slot);
  963. if (certHandle == NULL) {
  964. return CKR_TOKEN_WRITE_PROTECTED;
  965. }
  966. crv = sftkdb_write(certHandle, object, &object->handle);
  967. sftk_freeDB(certHandle);
  968. return crv;
  969. }
  970. return CKR_OK;
  971. }
  972. static NSSLOWKEYPrivateKey *
  973. sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key, CK_RV *rvp);
  974. static SECStatus
  975. sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded);
  976. /*
  977. * check the consistancy and initialize a Private Key Object
  978. */
  979. static CK_RV
  980. sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYPE key_type)
  981. {
  982. CK_BBOOL cktrue = CK_TRUE;
  983. CK_BBOOL encrypt = CK_TRUE;
  984. CK_BBOOL sign = CK_FALSE;
  985. CK_BBOOL recover = CK_TRUE;
  986. CK_BBOOL wrap = CK_TRUE;
  987. CK_BBOOL derive = CK_TRUE;
  988. CK_BBOOL ckfalse = CK_FALSE;
  989. PRBool createObjectInfo = PR_TRUE;
  990. PRBool fillPrivateKey = PR_FALSE;
  991. int missing_rsa_mod_component = 0;
  992. int missing_rsa_exp_component = 0;
  993. int missing_rsa_crt_component = 0;
  994. SECItem mod;
  995. CK_RV crv;
  996. SECStatus rv;
  997. switch (key_type) {
  998. case CKK_RSA:
  999. if (!sftk_hasAttribute(object, CKA_MODULUS)) {
  1000. missing_rsa_mod_component++;
  1001. }
  1002. if (!sftk_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
  1003. missing_rsa_exp_component++;
  1004. }
  1005. if (!sftk_hasAttribute(object, CKA_PRIVATE_EXPONENT)) {
  1006. missing_rsa_exp_component++;
  1007. }
  1008. if (!sftk_hasAttribute(object, CKA_PRIME_1)) {
  1009. missing_rsa_mod_component++;
  1010. }
  1011. if (!sftk_hasAttribute(object, CKA_PRIME_2)) {
  1012. missing_rsa_mod_component++;
  1013. }
  1014. if (!sftk_hasAttribute(object, CKA_EXPONENT_1)) {
  1015. missing_rsa_crt_component++;
  1016. }
  1017. if (!sftk_hasAttribute(object, CKA_EXPONENT_2)) {
  1018. missing_rsa_crt_component++;
  1019. }
  1020. if (!sftk_hasAttribute(object, CKA_COEFFICIENT)) {
  1021. missing_rsa_crt_component++;
  1022. }
  1023. if (missing_rsa_mod_component || missing_rsa_exp_component ||
  1024. missing_rsa_crt_component) {
  1025. /* we are missing a component, see if we have enough to rebuild
  1026. * the rest */
  1027. int have_exp = 2 - missing_rsa_exp_component;
  1028. int have_component = 5 -
  1029. (missing_rsa_exp_component + missing_rsa_mod_component);
  1030. if ((have_exp == 0) || (have_component < 3)) {
  1031. /* nope, not enough to reconstruct the private key */
  1032. return CKR_TEMPLATE_INCOMPLETE;
  1033. }
  1034. fillPrivateKey = PR_TRUE;
  1035. }
  1036. /*verify the parameters for consistency*/
  1037. rv = sftk_verifyRSAPrivateKey(object, fillPrivateKey);
  1038. if (rv != SECSuccess) {
  1039. return CKR_TEMPLATE_INCOMPLETE;
  1040. }
  1041. /* make sure Netscape DB attribute is set correctly */
  1042. crv = sftk_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS);
  1043. if (crv != CKR_OK)
  1044. return crv;
  1045. crv = sftk_forceAttribute(object, CKA_NSS_DB,
  1046. sftk_item_expand(&mod));
  1047. if (mod.data)
  1048. PORT_Free(mod.data);
  1049. if (crv != CKR_OK)
  1050. return crv;
  1051. sign = CK_TRUE;
  1052. derive = CK_FALSE;
  1053. break;
  1054. case CKK_DSA:
  1055. if (!sftk_hasAttribute(object, CKA_SUBPRIME)) {
  1056. return CKR_TEMPLATE_INCOMPLETE;
  1057. }
  1058. sign = CK_TRUE;
  1059. derive = CK_FALSE;
  1060. /* fall through */
  1061. case CKK_DH:
  1062. if (!sftk_hasAttribute(object, CKA_PRIME)) {
  1063. return CKR_TEMPLATE_INCOMPLETE;
  1064. }
  1065. if (!sftk_hasAttribute(object, CKA_BASE)) {
  1066. return CKR_TEMPLATE_INCOMPLETE;
  1067. }
  1068. if (!sftk_hasAttribute(object, CKA_VALUE)) {
  1069. return CKR_TEMPLATE_INCOMPLETE;
  1070. }
  1071. encrypt = CK_FALSE;
  1072. recover = CK_FALSE;
  1073. wrap = CK_FALSE;
  1074. break;
  1075. case CKK_EC:
  1076. if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) {
  1077. return CKR_TEMPLATE_INCOMPLETE;
  1078. }
  1079. if (!sftk_hasAttribute(object, CKA_VALUE)) {
  1080. return CKR_TEMPLATE_INCOMPLETE;
  1081. }
  1082. encrypt = CK_FALSE;
  1083. sign = CK_TRUE;
  1084. recover = CK_FALSE;
  1085. wrap = CK_FALSE;
  1086. break;
  1087. case CKK_NSS_JPAKE_ROUND1:
  1088. if (!sftk_hasAttribute(object, CKA_PRIME) ||
  1089. !sftk_hasAttribute(object, CKA_SUBPRIME) ||
  1090. !sftk_hasAttribute(object, CKA_BASE)) {
  1091. return CKR_TEMPLATE_INCOMPLETE;
  1092. }
  1093. /* fall through */
  1094. case CKK_NSS_JPAKE_ROUND2:
  1095. /* CKA_NSS_JPAKE_SIGNERID and CKA_NSS_JPAKE_PEERID are checked in
  1096. the J-PAKE code. */
  1097. encrypt = sign = recover = wrap = CK_FALSE;
  1098. derive = CK_TRUE;
  1099. createObjectInfo = PR_FALSE;
  1100. break;
  1101. default:
  1102. return CKR_ATTRIBUTE_VALUE_INVALID;
  1103. }
  1104. crv = sftk_defaultAttribute(object, CKA_SUBJECT, NULL, 0);
  1105. if (crv != CKR_OK)
  1106. return crv;
  1107. crv = sftk_defaultAttribute(object, CKA_SENSITIVE, &cktrue, sizeof(CK_BBOOL));
  1108. if (crv != CKR_OK)
  1109. return crv;
  1110. crv = sftk_defaultAttribute(object, CKA_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL));
  1111. if (crv != CKR_OK)
  1112. return crv;
  1113. crv = sftk_defaultAttribute(object, CKA_DECRYPT, &encrypt, sizeof(CK_BBOOL));
  1114. if (crv != CKR_OK)
  1115. return crv;
  1116. crv = sftk_defaultAttribute(object, CKA_SIGN, &sign, sizeof(CK_BBOOL));
  1117. if (crv != CKR_OK)
  1118. return crv;
  1119. crv = sftk_defaultAttribute(object, CKA_SIGN_RECOVER, &recover,
  1120. sizeof(CK_BBOOL));
  1121. if (crv != CKR_OK)
  1122. return crv;
  1123. crv = sftk_defaultAttribute(object, CKA_UNWRAP, &wrap, sizeof(CK_BBOOL));
  1124. if (crv != CKR_OK)
  1125. return crv;
  1126. crv = sftk_defaultAttribute(object, CKA_DERIVE, &derive, sizeof(CK_BBOOL));
  1127. if (crv != CKR_OK)
  1128. return crv;
  1129. /* the next two bits get modified only in the key gen and token cases */
  1130. crv = sftk_forceAttribute(object, CKA_ALWAYS_SENSITIVE,
  1131. &ckfalse, sizeof(CK_BBOOL));
  1132. if (crv != CKR_OK)
  1133. return crv;
  1134. crv = sftk_forceAttribute(object, CKA_NEVER_EXTRACTABLE,
  1135. &ckfalse, sizeof(CK_BBOOL));
  1136. if (crv != CKR_OK)
  1137. return crv;
  1138. /* should we check the non-token RSA private keys? */
  1139. if (sftk_isTrue(object, CKA_TOKEN)) {
  1140. SFTKSlot *slot = session->slot;
  1141. SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
  1142. if (keyHandle == NULL) {
  1143. return CKR_TOKEN_WRITE_PROTECTED;
  1144. }
  1145. crv = sftkdb_write(keyHandle, object, &object->handle);
  1146. sftk_freeDB(keyHandle);
  1147. return crv;
  1148. } else if (createObjectInfo) {
  1149. object->objectInfo = sftk_mkPrivKey(object, key_type, &crv);
  1150. if (object->objectInfo == NULL)
  1151. return crv;
  1152. object->infoFree = (SFTKFree)nsslowkey_DestroyPrivateKey;
  1153. }
  1154. return CKR_OK;
  1155. }
  1156. /* forward declare the DES formating function for handleSecretKey */
  1157. void sftk_FormatDESKey(unsigned char *key, int length);
  1158. /* Validate secret key data, and set defaults */
  1159. static CK_RV
  1160. validateSecretKey(SFTKSession *session, SFTKObject *object,
  1161. CK_KEY_TYPE key_type, PRBool isFIPS)
  1162. {
  1163. CK_RV crv;
  1164. CK_BBOOL cktrue = CK_TRUE;
  1165. CK_BBOOL ckfalse = CK_FALSE;
  1166. SFTKAttribute *attribute = NULL;
  1167. unsigned long requiredLen;
  1168. crv = sftk_defaultAttribute(object, CKA_SENSITIVE,
  1169. isFIPS ? &cktrue : &ckfalse, sizeof(CK_BBOOL));
  1170. if (crv != CKR_OK)
  1171. return crv;
  1172. crv = sftk_defaultAttribute(object, CKA_EXTRACTABLE,
  1173. &cktrue, sizeof(CK_BBOOL));
  1174. if (crv != CKR_OK)
  1175. return crv;
  1176. crv = sftk_defaultAttribute(object, CKA_ENCRYPT, &cktrue, sizeof(CK_BBOOL));
  1177. if (crv != CKR_OK)
  1178. return crv;
  1179. crv = sftk_defaultAttribute(object, CKA_DECRYPT, &cktrue, sizeof(CK_BBOOL));
  1180. if (crv != CKR_OK)
  1181. return crv;
  1182. crv = sftk_defaultAttribute(object, CKA_SIGN, &ckfalse, sizeof(CK_BBOOL));
  1183. if (crv != CKR_OK)
  1184. return crv;
  1185. crv = sftk_defaultAttribute(object, CKA_VERIFY, &ckfalse, sizeof(CK_BBOOL));
  1186. if (crv != CKR_OK)
  1187. return crv;
  1188. crv = sftk_defaultAttribute(object, CKA_WRAP, &cktrue, sizeof(CK_BBOOL));
  1189. if (crv != CKR_OK)
  1190. return crv;
  1191. crv = sftk_defaultAttribute(object, CKA_UNWRAP, &cktrue, sizeof(CK_BBOOL));
  1192. if (crv != CKR_OK)
  1193. return crv;
  1194. if (!sftk_hasAttribute(object, CKA_VALUE)) {
  1195. return CKR_TEMPLATE_INCOMPLETE;
  1196. }
  1197. /* the next two bits get modified only in the key gen and token cases */
  1198. crv = sftk_forceAttribute(object, CKA_ALWAYS_SENSITIVE,
  1199. &ckfalse, sizeof(CK_BBOOL));
  1200. if (crv != CKR_OK)
  1201. return crv;
  1202. crv = sftk_forceAttribute(object, CKA_NEVER_EXTRACTABLE,
  1203. &ckfalse, sizeof(CK_BBOOL));
  1204. if (crv != CKR_OK)
  1205. return crv;
  1206. /* some types of keys have a value length */
  1207. crv = CKR_OK;
  1208. switch (key_type) {
  1209. /* force CKA_VALUE_LEN to be set */
  1210. case CKK_GENERIC_SECRET:
  1211. case CKK_RC2:
  1212. case CKK_RC4:
  1213. #if NSS_SOFTOKEN_DOES_RC5
  1214. case CKK_RC5:
  1215. #endif
  1216. #ifdef NSS_SOFTOKEN_DOES_CAST
  1217. case CKK_CAST:
  1218. case CKK_CAST3:
  1219. case CKK_CAST5:
  1220. #endif
  1221. #if NSS_SOFTOKEN_DOES_IDEA
  1222. case CKK_IDEA:
  1223. #endif
  1224. attribute = sftk_FindAttribute(object, CKA_VALUE);
  1225. /* shouldn't happen */
  1226. if (attribute == NULL)
  1227. return CKR_TEMPLATE_INCOMPLETE;
  1228. crv = sftk_forceAttribute(object, CKA_VALUE_LEN,
  1229. &attribute->attrib.ulValueLen, sizeof(CK_ULONG));
  1230. sftk_FreeAttribute(attribute);
  1231. break;
  1232. /* force the value to have the correct parity */
  1233. case CKK_DES:
  1234. case CKK_DES2:
  1235. case CKK_DES3:
  1236. case CKK_CDMF:
  1237. attribute = sftk_FindAttribute(object, CKA_VALUE);
  1238. /* shouldn't happen */
  1239. if (attribute == NULL)
  1240. return CKR_TEMPLATE_INCOMPLETE;
  1241. requiredLen = sftk_MapKeySize(key_type);
  1242. if (attribute->attrib.ulValueLen != requiredLen) {
  1243. sftk_FreeAttribute(attribute);
  1244. return CKR_KEY_SIZE_RANGE;
  1245. }
  1246. sftk_FormatDESKey((unsigned char *)attribute->attrib.pValue,
  1247. attribute->attrib.ulValueLen);
  1248. sftk_FreeAttribute(attribute);
  1249. break;
  1250. case CKK_AES:
  1251. attribute = sftk_FindAttribute(object, CKA_VALUE);
  1252. /* shouldn't happen */
  1253. if (attribute == NULL)
  1254. return CKR_TEMPLATE_INCOMPLETE;
  1255. if (attribute->attrib.ulValueLen != 16 &&
  1256. attribute->attrib.ulValueLen != 24 &&
  1257. attribute->attrib.ulValueLen != 32) {
  1258. sftk_FreeAttribute(attribute);
  1259. return CKR_KEY_SIZE_RANGE;
  1260. }
  1261. crv = sftk_forceAttribute(object, CKA_VALUE_LEN,
  1262. &attribute->attrib.ulValueLen, sizeof(CK_ULONG));
  1263. sftk_FreeAttribute(attribute);
  1264. break;
  1265. default:
  1266. break;
  1267. }
  1268. return crv;
  1269. }
  1270. /*
  1271. * check the consistancy and initialize a Secret Key Object
  1272. */
  1273. static CK_RV
  1274. sftk_handleSecretKeyObject(SFTKSession *session, SFTKObject *object,
  1275. CK_KEY_TYPE key_type, PRBool isFIPS)
  1276. {
  1277. CK_RV crv;
  1278. /* First validate and set defaults */
  1279. crv = validateSecretKey(session, object, key_type, isFIPS);
  1280. if (crv != CKR_OK)
  1281. goto loser;
  1282. /* If the object is a TOKEN object, store in the database */
  1283. if (sftk_isTrue(object, CKA_TOKEN)) {
  1284. SFTKSlot *slot = session->slot;
  1285. SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
  1286. if (keyHandle == NULL) {
  1287. return CKR_TOKEN_WRITE_PROTECTED;
  1288. }
  1289. crv = sftkdb_write(keyHandle, object, &object->handle);
  1290. sftk_freeDB(keyHandle);
  1291. return crv;
  1292. }
  1293. loser:
  1294. return crv;
  1295. }
  1296. /*
  1297. * check the consistancy and initialize a Key Object
  1298. */
  1299. static CK_RV
  1300. sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
  1301. {
  1302. SFTKAttribute *attribute;
  1303. CK_KEY_TYPE key_type;
  1304. CK_BBOOL ckfalse = CK_FALSE;
  1305. CK_RV crv;
  1306. /* verify the required fields */
  1307. if (!sftk_hasAttribute(object, CKA_KEY_TYPE)) {
  1308. return CKR_TEMPLATE_INCOMPLETE;
  1309. }
  1310. /* now verify the common fields */
  1311. crv = sftk_defaultAttribute(object, CKA_ID, NULL, 0);
  1312. if (crv != CKR_OK)
  1313. return crv;
  1314. crv = sftk_defaultAttribute(object, CKA_START_DATE, NULL, 0);
  1315. if (crv != CKR_OK)
  1316. return crv;
  1317. crv = sftk_defaultAttribute(object, CKA_END_DATE, NULL, 0);
  1318. if (crv != CKR_OK)
  1319. return crv;
  1320. /* CKA_DERIVE is common to all keys, but it's default value is
  1321. * key dependent */
  1322. crv = sftk_defaultAttribute(object, CKA_LOCAL, &ckfalse, sizeof(CK_BBOOL));
  1323. if (crv != CKR_OK)
  1324. return crv;
  1325. /* get the key type */
  1326. attribute = sftk_FindAttribute(object, CKA_KEY_TYPE);
  1327. if (!attribute) {
  1328. return CKR_ATTRIBUTE_VALUE_INVALID;
  1329. }
  1330. key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
  1331. sftk_FreeAttribute(attribute);
  1332. switch (object->objclass) {
  1333. case CKO_PUBLIC_KEY:
  1334. return sftk_handlePublicKeyObject(session, object, key_type);
  1335. case CKO_PRIVATE_KEY:
  1336. return sftk_handlePrivateKeyObject(session, object, key_type);
  1337. case CKO_SECRET_KEY:
  1338. /* make sure the required fields exist */
  1339. return sftk_handleSecretKeyObject(session, object, key_type,
  1340. (PRBool)(session->slot->slotID == FIPS_SLOT_ID));
  1341. default:
  1342. break;
  1343. }
  1344. return CKR_ATTRIBUTE_VALUE_INVALID;
  1345. }
  1346. /*
  1347. * check the consistancy and Verify a DSA Parameter Object
  1348. */
  1349. static CK_RV
  1350. sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object)
  1351. {
  1352. SFTKAttribute *primeAttr = NULL;
  1353. SFTKAttribute *subPrimeAttr = NULL;
  1354. SFTKAttribute *baseAttr = NULL;
  1355. SFTKAttribute *seedAttr = NULL;
  1356. SFTKAttribute *hAttr = NULL;
  1357. SFTKAttribute *attribute;
  1358. CK_RV crv = CKR_TEMPLATE_INCOMPLETE;
  1359. PQGParams params;
  1360. PQGVerify vfy, *verify = NULL;
  1361. SECStatus result, rv;
  1362. /* This bool keeps track of whether or not we need verify parameters.
  1363. * If a P, Q and G or supplied, we dont' need verify parameters, as we
  1364. * have PQ and G.
  1365. * - If G is not supplied, the presumption is that we want to
  1366. * verify P and Q only.
  1367. * - If counter is supplied, it is presumed we want to verify PQ because
  1368. * the counter is only used in verification.
  1369. * - If H is supplied, is is presumed we want to verify G because H is
  1370. * only used to verify G.
  1371. * - Any verification step must have the SEED (counter or H could be
  1372. * missing depending on exactly what we want to verify). If SEED is supplied,
  1373. * the code just goes ahead and runs verify (other errors are parameter
  1374. * errors are detected by the PQG_VerifyParams function). If SEED is not
  1375. * supplied, but we determined that we are trying to verify (because needVfy
  1376. * is set, go ahead and return CKR_TEMPLATE_INCOMPLETE.
  1377. */
  1378. PRBool needVfy = PR_FALSE;
  1379. primeAttr = sftk_FindAttribute(object, CKA_PRIME);
  1380. if (primeAttr == NULL)
  1381. goto loser;
  1382. params.prime.data = primeAttr->attrib.pValue;
  1383. params.prime.len = primeAttr->attrib.ulValueLen;
  1384. subPrimeAttr = sftk_FindAttribute(object, CKA_SUBPRIME);
  1385. if (subPrimeAttr == NULL)
  1386. goto loser;
  1387. params.subPrime.data = subPrimeAttr->attrib.pValue;
  1388. params.subPrime.len = subPrimeAttr->attrib.ulValueLen;
  1389. baseAttr = sftk_FindAttribute(object, CKA_BASE);
  1390. if (baseAttr != NULL) {
  1391. params.base.data = baseAttr->attrib.pValue;
  1392. params.base.len = baseAttr->attrib.ulValueLen;
  1393. } else {
  1394. params.base.data = NULL;
  1395. params.base.len = 0;
  1396. needVfy = PR_TRUE; /* presumably only including PQ so we can verify
  1397. * them. */
  1398. }
  1399. attribute = sftk_FindAttribute(object, CKA_NSS_PQG_COUNTER);
  1400. if (attribute != NULL) {
  1401. vfy.counter = *(CK_ULONG *)attribute->attrib.pValue;
  1402. sftk_FreeAttribute(attribute);
  1403. needVfy = PR_TRUE; /* included a count so we can verify PQ */
  1404. } else {
  1405. vfy.counter = -1;
  1406. }
  1407. hAttr = sftk_FindAttribute(object, CKA_NSS_PQG_H);
  1408. if (hAttr != NULL) {
  1409. vfy.h.data = hAttr->attrib.pValue;
  1410. vfy.h.len = hAttr->attrib.ulValueLen;
  1411. needVfy = PR_TRUE; /* included H so we can verify G */
  1412. } else {
  1413. vfy.h.data = NULL;
  1414. vfy.h.len = 0;
  1415. }
  1416. seedAttr = sftk_FindAttribute(object, CKA_NSS_PQG_SEED);
  1417. if (seedAttr != NULL) {
  1418. vfy.seed.data = seedAttr->attrib.pValue;
  1419. vfy.seed.len = seedAttr->attrib.ulValueLen;
  1420. verify = &vfy;
  1421. } else if (needVfy) {
  1422. goto loser; /* Verify always needs seed, if we need verify and not seed
  1423. * then fail */
  1424. }
  1425. crv = CKR_FUNCTION_FAILED;
  1426. rv = PQG_VerifyParams(&params, verify, &result);
  1427. if (rv == SECSuccess) {
  1428. crv = (result == SECSuccess) ? CKR_OK : CKR_ATTRIBUTE_VALUE_INVALID;
  1429. }
  1430. loser:
  1431. if (hAttr)
  1432. sftk_FreeAttribute(hAttr);
  1433. if (seedAttr)
  1434. sftk_FreeAttribute(seedAttr);
  1435. if (baseAttr)
  1436. sftk_FreeAttribute(baseAttr);
  1437. if (subPrimeAttr)
  1438. sftk_FreeAttribute(subPrimeAttr);
  1439. if (primeAttr)
  1440. sftk_FreeAttribute(primeAttr);
  1441. return crv;
  1442. }
  1443. /*
  1444. * check the consistancy and initialize a Key Parameter Object
  1445. */
  1446. static CK_RV
  1447. sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
  1448. {
  1449. SFTKAttribute *attribute;
  1450. CK_KEY_TYPE key_type;
  1451. CK_BBOOL ckfalse = CK_FALSE;
  1452. CK_RV crv;
  1453. /* verify the required fields */
  1454. if (!sftk_hasAttribute(object, CKA_KEY_TYPE)) {
  1455. return CKR_TEMPLATE_INCOMPLETE;
  1456. }
  1457. /* now verify the common fields */
  1458. crv = sftk_defaultAttribute(object, CKA_LOCAL, &ckfalse, sizeof(CK_BBOOL));
  1459. if (crv != CKR_OK)
  1460. return crv;
  1461. /* get the key type */
  1462. attribute = sftk_FindAttribute(object, CKA_KEY_TYPE);
  1463. if (!attribute) {
  1464. return CKR_ATTRIBUTE_VALUE_INVALID;
  1465. }
  1466. key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
  1467. sftk_FreeAttribute(attribute);
  1468. switch (key_type) {
  1469. case CKK_DSA:
  1470. return sftk_handleDSAParameterObject(session, object);
  1471. default:
  1472. break;
  1473. }
  1474. return CKR_KEY_TYPE_INCONSISTENT;
  1475. }
  1476. /*
  1477. * Handle Object does all the object consistancy checks, automatic attribute
  1478. * generation, attribute defaulting, etc. If handleObject succeeds, the object
  1479. * will be assigned an object handle, and the object installed in the session
  1480. * or stored in the DB.
  1481. */
  1482. CK_RV
  1483. sftk_handleObject(SFTKObject *object, SFTKSession *session)
  1484. {
  1485. SFTKSlot *slot = session->slot;
  1486. SFTKAttribute *attribute;
  1487. SFTKObject *duplicateObject = NULL;
  1488. CK_OBJECT_HANDLE handle;
  1489. CK_BBOOL ckfalse = CK_FALSE;
  1490. CK_BBOOL cktrue = CK_TRUE;
  1491. CK_RV crv;
  1492. /* make sure all the base object types are defined. If not set the
  1493. * defaults */
  1494. crv = sftk_defaultAttribute(object, CKA_TOKEN, &ckfalse, sizeof(CK_BBOOL));
  1495. if (crv != CKR_OK)
  1496. return crv;
  1497. crv = sftk_defaultAttribute(object, CKA_PRIVATE, &ckfalse, sizeof(CK_BBOOL));
  1498. if (crv != CKR_OK)
  1499. return crv;
  1500. crv = sftk_defaultAttribute(object, CKA_LABEL, NULL, 0);
  1501. if (crv != CKR_OK)
  1502. return crv;
  1503. crv = sftk_defaultAttribute(object, CKA_MODIFIABLE, &cktrue, sizeof(CK_BBOOL));
  1504. if (crv != CKR_OK)
  1505. return crv;
  1506. /* don't create a private object if we aren't logged in */
  1507. if ((!slot->isLoggedIn) && (slot->needLogin) &&
  1508. (sftk_isTrue(object, CKA_PRIVATE))) {
  1509. return CKR_USER_NOT_LOGGED_IN;
  1510. }
  1511. if (((session->info.flags & CKF_RW_SESSION) == 0) &&
  1512. (sftk_isTrue(object, CKA_TOKEN))) {
  1513. return CKR_SESSION_READ_ONLY;
  1514. }
  1515. /* Assign a unique SESSION object handle to every new object,
  1516. * whether it is a session object or a token object.
  1517. * At this point, all new objects are structured as session objects.
  1518. * Objects with the CKA_TOKEN attribute true will be turned into
  1519. * token objects and will have a token object handle assigned to
  1520. * them by a call to sftk_mkHandle in the handler for each object
  1521. * class, invoked below.
  1522. *
  1523. * It may be helpful to note/remember that
  1524. * sftk_narrowToXxxObject uses sftk_isToken,
  1525. * sftk_isToken examines the sign bit of the object's handle, but
  1526. * sftk_isTrue(...,CKA_TOKEN) examines the CKA_TOKEN attribute.
  1527. */
  1528. do {
  1529. PRUint32 wrappedAround;
  1530. duplicateObject = NULL;
  1531. PZ_Lock(slot->objectLock);
  1532. wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK;
  1533. handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK;
  1534. if (!handle) /* don't allow zero handle */
  1535. handle = minSessionObjectHandle;
  1536. slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround;
  1537. /* Is there already a session object with this handle? */
  1538. if (wrappedAround) {
  1539. sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable,
  1540. slot->sessObjHashSize);
  1541. }
  1542. PZ_Unlock(slot->objectLock);
  1543. } while (duplicateObject != NULL);
  1544. object->handle = handle;
  1545. /* get the object class */
  1546. attribute = sftk_FindAttribute(object, CKA_CLASS);
  1547. if (attribute == NULL) {
  1548. return CKR_TEMPLATE_INCOMPLETE;
  1549. }
  1550. object->objclass = *(CK_OBJECT_CLASS *)attribute->attrib.pValue;
  1551. sftk_FreeAttribute(attribute);
  1552. /* Now handle the specific object class.
  1553. * At this point, all objects are session objects, and the session
  1554. * number must be passed to the object class handlers.
  1555. */
  1556. switch (object->objclass) {
  1557. case CKO_DATA:
  1558. crv = sftk_handleDataObject(session, object);
  1559. break;
  1560. case CKO_CERTIFICATE:
  1561. crv = sftk_handleCertObject(session, object);
  1562. break;
  1563. case CKO_NSS_TRUST:
  1564. crv = sftk_handleTrustObject(session, object);
  1565. break;
  1566. case CKO_NSS_CRL:
  1567. crv = sftk_handleCrlObject(session, object);
  1568. break;
  1569. case CKO_NSS_SMIME:
  1570. crv = sftk_handleSMimeObject(session, object);
  1571. break;
  1572. case CKO_PRIVATE_KEY:
  1573. case CKO_PUBLIC_KEY:
  1574. case CKO_SECRET_KEY:
  1575. crv = sftk_handleKeyObject(session, object);
  1576. break;
  1577. case CKO_DOMAIN_PARAMETERS:
  1578. crv = sftk_handleKeyParameterObject(session, object);
  1579. break;
  1580. default:
  1581. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  1582. break;
  1583. }
  1584. /* can't fail from here on out unless the pk_handlXXX functions have
  1585. * failed the request */
  1586. if (crv != CKR_OK) {
  1587. return crv;
  1588. }
  1589. /* Now link the object into the slot and session structures.
  1590. * If the object has a true CKA_TOKEN attribute, the above object
  1591. * class handlers will have set the sign bit in the object handle,
  1592. * causing the following test to be true.
  1593. */
  1594. if (sftk_isToken(object->handle)) {
  1595. sftk_convertSessionToToken(object);
  1596. } else {
  1597. object->slot = slot;
  1598. sftk_AddObject(session, object);
  1599. }
  1600. return CKR_OK;
  1601. }
  1602. /*
  1603. * ******************** Public Key Utilities ***************************
  1604. */
  1605. /* Generate a low public key structure from an object */
  1606. NSSLOWKEYPublicKey *
  1607. sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type,
  1608. CK_RV *crvp)
  1609. {
  1610. NSSLOWKEYPublicKey *pubKey;
  1611. PLArenaPool *arena;
  1612. CK_RV crv;
  1613. if (object->objclass != CKO_PUBLIC_KEY) {
  1614. *crvp = CKR_KEY_TYPE_INCONSISTENT;
  1615. return NULL;
  1616. }
  1617. if (sftk_isToken(object->handle)) {
  1618. /* ferret out the token object handle */
  1619. }
  1620. /* If we already have a key, use it */
  1621. if (object->objectInfo) {
  1622. *crvp = CKR_OK;
  1623. return (NSSLOWKEYPublicKey *)object->objectInfo;
  1624. }
  1625. /* allocate the structure */
  1626. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  1627. if (arena == NULL) {
  1628. *crvp = CKR_HOST_MEMORY;
  1629. return NULL;
  1630. }
  1631. pubKey = (NSSLOWKEYPublicKey *)
  1632. PORT_ArenaAlloc(arena, sizeof(NSSLOWKEYPublicKey));
  1633. if (pubKey == NULL) {
  1634. PORT_FreeArena(arena, PR_FALSE);
  1635. *crvp = CKR_HOST_MEMORY;
  1636. return NULL;
  1637. }
  1638. /* fill in the structure */
  1639. pubKey->arena = arena;
  1640. switch (key_type) {
  1641. case CKK_RSA:
  1642. pubKey->keyType = NSSLOWKEYRSAKey;
  1643. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.rsa.modulus,
  1644. object, CKA_MODULUS);
  1645. if (crv != CKR_OK)
  1646. break;
  1647. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.rsa.publicExponent,
  1648. object, CKA_PUBLIC_EXPONENT);
  1649. break;
  1650. case CKK_DSA:
  1651. pubKey->keyType = NSSLOWKEYDSAKey;
  1652. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dsa.params.prime,
  1653. object, CKA_PRIME);
  1654. if (crv != CKR_OK)
  1655. break;
  1656. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dsa.params.subPrime,
  1657. object, CKA_SUBPRIME);
  1658. if (crv != CKR_OK)
  1659. break;
  1660. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dsa.params.base,
  1661. object, CKA_BASE);
  1662. if (crv != CKR_OK)
  1663. break;
  1664. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dsa.publicValue,
  1665. object, CKA_VALUE);
  1666. break;
  1667. case CKK_DH:
  1668. pubKey->keyType = NSSLOWKEYDHKey;
  1669. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.prime,
  1670. object, CKA_PRIME);
  1671. if (crv != CKR_OK)
  1672. break;
  1673. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.base,
  1674. object, CKA_BASE);
  1675. if (crv != CKR_OK)
  1676. break;
  1677. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.publicValue,
  1678. object, CKA_VALUE);
  1679. break;
  1680. case CKK_EC:
  1681. pubKey->keyType = NSSLOWKEYECKey;
  1682. crv = sftk_Attribute2SSecItem(arena,
  1683. &pubKey->u.ec.ecParams.DEREncoding,
  1684. object, CKA_EC_PARAMS);
  1685. if (crv != CKR_OK)
  1686. break;
  1687. /* Fill out the rest of the ecParams structure
  1688. * based on the encoded params
  1689. */
  1690. if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding,
  1691. &pubKey->u.ec.ecParams) != SECSuccess) {
  1692. crv = CKR_DOMAIN_PARAMS_INVALID;
  1693. break;
  1694. }
  1695. crv = sftk_Attribute2SSecItem(arena, &pubKey->u.ec.publicValue,
  1696. object, CKA_EC_POINT);
  1697. if (crv == CKR_OK) {
  1698. unsigned int keyLen = EC_GetPointSize(&pubKey->u.ec.ecParams);
  1699. /* special note: We can't just use the first byte to distinguish
  1700. * between EC_POINT_FORM_UNCOMPRESSED and SEC_ASN1_OCTET_STRING.
  1701. * Both are 0x04. */
  1702. /* Handle the non-DER encoded case.
  1703. * Some curves are always pressumed to be non-DER.
  1704. */
  1705. if (pubKey->u.ec.publicValue.len == keyLen &&
  1706. (pubKey->u.ec.ecParams.fieldID.type == ec_field_plain ||
  1707. pubKey->u.ec.publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED)) {
  1708. break; /* key was not DER encoded, no need to unwrap */
  1709. }
  1710. /* handle the encoded case */
  1711. if ((pubKey->u.ec.publicValue.data[0] == SEC_ASN1_OCTET_STRING) &&
  1712. pubKey->u.ec.publicValue.len > keyLen) {
  1713. SECItem publicValue;
  1714. SECStatus rv;
  1715. rv = SEC_QuickDERDecodeItem(arena, &publicValue,
  1716. SEC_ASN1_GET(SEC_OctetStringTemplate),
  1717. &pubKey->u.ec.publicValue);
  1718. /* nope, didn't decode correctly */
  1719. if ((rv != SECSuccess) || (publicValue.len != keyLen)) {
  1720. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  1721. break;
  1722. }
  1723. /* we don't handle compressed points except in the case of ECCurve25519 */
  1724. if ((pubKey->u.ec.ecParams.fieldID.type != ec_field_plain) &&
  1725. (publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED)) {
  1726. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  1727. break;
  1728. }
  1729. /* replace our previous with the decoded key */
  1730. pubKey->u.ec.publicValue = publicValue;
  1731. break;
  1732. }
  1733. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  1734. }
  1735. break;
  1736. default:
  1737. crv = CKR_KEY_TYPE_INCONSISTENT;
  1738. break;
  1739. }
  1740. *crvp = crv;
  1741. if (crv != CKR_OK) {
  1742. PORT_FreeArena(arena, PR_FALSE);
  1743. return NULL;
  1744. }
  1745. object->objectInfo = pubKey;
  1746. object->infoFree = (SFTKFree)nsslowkey_DestroyPublicKey;
  1747. return pubKey;
  1748. }
  1749. /* make a private key from a verified object */
  1750. static NSSLOWKEYPrivateKey *
  1751. sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
  1752. {
  1753. NSSLOWKEYPrivateKey *privKey;
  1754. SFTKItemTemplate itemTemplate[SFTK_MAX_ITEM_TEMPLATE];
  1755. int itemTemplateCount = 0;
  1756. PLArenaPool *arena;
  1757. CK_RV crv = CKR_OK;
  1758. SECStatus rv;
  1759. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  1760. if (arena == NULL) {
  1761. *crvp = CKR_HOST_MEMORY;
  1762. return NULL;
  1763. }
  1764. privKey = (NSSLOWKEYPrivateKey *)
  1765. PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPrivateKey));
  1766. if (privKey == NULL) {
  1767. PORT_FreeArena(arena, PR_FALSE);
  1768. *crvp = CKR_HOST_MEMORY;
  1769. return NULL;
  1770. }
  1771. /* in future this would be a switch on key_type */
  1772. privKey->arena = arena;
  1773. switch (key_type) {
  1774. case CKK_RSA:
  1775. privKey->keyType = NSSLOWKEYRSAKey;
  1776. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1777. &privKey->u.rsa.modulus, CKA_MODULUS);
  1778. itemTemplateCount++;
  1779. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1780. &privKey->u.rsa.publicExponent, CKA_PUBLIC_EXPONENT);
  1781. itemTemplateCount++;
  1782. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1783. &privKey->u.rsa.privateExponent, CKA_PRIVATE_EXPONENT);
  1784. itemTemplateCount++;
  1785. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1786. &privKey->u.rsa.prime1, CKA_PRIME_1);
  1787. itemTemplateCount++;
  1788. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1789. &privKey->u.rsa.prime2, CKA_PRIME_2);
  1790. itemTemplateCount++;
  1791. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1792. &privKey->u.rsa.exponent1, CKA_EXPONENT_1);
  1793. itemTemplateCount++;
  1794. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1795. &privKey->u.rsa.exponent2, CKA_EXPONENT_2);
  1796. itemTemplateCount++;
  1797. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1798. &privKey->u.rsa.coefficient, CKA_COEFFICIENT);
  1799. itemTemplateCount++;
  1800. rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,
  1801. NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
  1802. if (rv != SECSuccess)
  1803. crv = CKR_HOST_MEMORY;
  1804. break;
  1805. case CKK_DSA:
  1806. privKey->keyType = NSSLOWKEYDSAKey;
  1807. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1808. &privKey->u.dsa.params.prime, CKA_PRIME);
  1809. itemTemplateCount++;
  1810. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1811. &privKey->u.dsa.params.subPrime, CKA_SUBPRIME);
  1812. itemTemplateCount++;
  1813. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1814. &privKey->u.dsa.params.base, CKA_BASE);
  1815. itemTemplateCount++;
  1816. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1817. &privKey->u.dsa.privateValue, CKA_VALUE);
  1818. itemTemplateCount++;
  1819. /* privKey was zero'd so public value is already set to NULL, 0
  1820. * if we don't set it explicitly */
  1821. break;
  1822. case CKK_DH:
  1823. privKey->keyType = NSSLOWKEYDHKey;
  1824. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1825. &privKey->u.dh.prime, CKA_PRIME);
  1826. itemTemplateCount++;
  1827. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1828. &privKey->u.dh.base, CKA_BASE);
  1829. itemTemplateCount++;
  1830. SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
  1831. &privKey->u.dh.privateValue, CKA_VALUE);
  1832. itemTemplateCount++;
  1833. /* privKey was zero'd so public value is already set to NULL, 0
  1834. * if we don't set it explicitly */
  1835. break;
  1836. case CKK_EC:
  1837. privKey->keyType = NSSLOWKEYECKey;
  1838. crv = sftk_Attribute2SSecItem(arena,
  1839. &privKey->u.ec.ecParams.DEREncoding,
  1840. object, CKA_EC_PARAMS);
  1841. if (crv != CKR_OK)
  1842. break;
  1843. /* Fill out the rest of the ecParams structure
  1844. * based on the encoded params
  1845. */
  1846. if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
  1847. &privKey->u.ec.ecParams) != SECSuccess) {
  1848. crv = CKR_DOMAIN_PARAMS_INVALID;
  1849. break;
  1850. }
  1851. crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.privateValue,
  1852. object, CKA_VALUE);
  1853. if (crv != CKR_OK)
  1854. break;
  1855. if (sftk_hasAttribute(object, CKA_NSS_DB)) {
  1856. crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue,
  1857. object, CKA_NSS_DB);
  1858. if (crv != CKR_OK)
  1859. break;
  1860. /* privKey was zero'd so public value is already set to NULL, 0
  1861. * if we don't set it explicitly */
  1862. }
  1863. rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version,
  1864. NSSLOWKEY_EC_PRIVATE_KEY_VERSION);
  1865. if (rv != SECSuccess) {
  1866. crv = CKR_HOST_MEMORY;
  1867. /* The following ifdef is needed for Linux arm distros and
  1868. * Android as gcc 4.6 has a bug when targeting arm (but not
  1869. * thumb). The bug has been fixed in gcc 4.7.
  1870. * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56561
  1871. */
  1872. #if defined(__arm__) && !defined(__thumb__) && defined(__GNUC__)
  1873. *crvp = CKR_HOST_MEMORY;
  1874. break;
  1875. #endif
  1876. }
  1877. break;
  1878. default:
  1879. crv = CKR_KEY_TYPE_INCONSISTENT;
  1880. break;
  1881. }
  1882. if (crv == CKR_OK && itemTemplateCount != 0) {
  1883. PORT_Assert(itemTemplateCount > 0);
  1884. PORT_Assert(itemTemplateCount <= SFTK_MAX_ITEM_TEMPLATE);
  1885. crv = sftk_MultipleAttribute2SecItem(arena, object, itemTemplate,
  1886. itemTemplateCount);
  1887. }
  1888. *crvp = crv;
  1889. if (crv != CKR_OK) {
  1890. PORT_FreeArena(arena, PR_FALSE);
  1891. return NULL;
  1892. }
  1893. return privKey;
  1894. }
  1895. /*
  1896. * If a partial RSA private key is present, fill in the rest if necessary,
  1897. * and then verify the parameters are well-formed
  1898. */
  1899. static SECStatus
  1900. sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded)
  1901. {
  1902. RSAPrivateKey tmpKey = { 0 };
  1903. SFTKAttribute *modulus = NULL;
  1904. SFTKAttribute *prime1 = NULL;
  1905. SFTKAttribute *prime2 = NULL;
  1906. SFTKAttribute *privateExponent = NULL;
  1907. SFTKAttribute *publicExponent = NULL;
  1908. SFTKAttribute *exponent1 = NULL;
  1909. SFTKAttribute *exponent2 = NULL;
  1910. SFTKAttribute *coefficient = NULL;
  1911. SECStatus rv;
  1912. CK_RV crv;
  1913. /* first fill in the components that we have. Populate only uses
  1914. * the non-crt components, so only fill those in */
  1915. tmpKey.arena = NULL;
  1916. modulus = sftk_FindAttribute(object, CKA_MODULUS);
  1917. if (modulus) {
  1918. tmpKey.modulus.data = modulus->attrib.pValue;
  1919. tmpKey.modulus.len = modulus->attrib.ulValueLen;
  1920. }
  1921. prime1 = sftk_FindAttribute(object, CKA_PRIME_1);
  1922. if (prime1) {
  1923. tmpKey.prime1.data = prime1->attrib.pValue;
  1924. tmpKey.prime1.len = prime1->attrib.ulValueLen;
  1925. }
  1926. prime2 = sftk_FindAttribute(object, CKA_PRIME_2);
  1927. if (prime2) {
  1928. tmpKey.prime2.data = prime2->attrib.pValue;
  1929. tmpKey.prime2.len = prime2->attrib.ulValueLen;
  1930. }
  1931. privateExponent = sftk_FindAttribute(object, CKA_PRIVATE_EXPONENT);
  1932. if (privateExponent) {
  1933. tmpKey.privateExponent.data = privateExponent->attrib.pValue;
  1934. tmpKey.privateExponent.len = privateExponent->attrib.ulValueLen;
  1935. }
  1936. publicExponent = sftk_FindAttribute(object, CKA_PUBLIC_EXPONENT);
  1937. if (publicExponent) {
  1938. tmpKey.publicExponent.data = publicExponent->attrib.pValue;
  1939. tmpKey.publicExponent.len = publicExponent->attrib.ulValueLen;
  1940. }
  1941. exponent1 = sftk_FindAttribute(object, CKA_EXPONENT_1);
  1942. if (exponent1) {
  1943. tmpKey.exponent1.data = exponent1->attrib.pValue;
  1944. tmpKey.exponent1.len = exponent1->attrib.ulValueLen;
  1945. }
  1946. exponent2 = sftk_FindAttribute(object, CKA_EXPONENT_2);
  1947. if (exponent2) {
  1948. tmpKey.exponent2.data = exponent2->attrib.pValue;
  1949. tmpKey.exponent2.len = exponent2->attrib.ulValueLen;
  1950. }
  1951. coefficient = sftk_FindAttribute(object, CKA_COEFFICIENT);
  1952. if (coefficient) {
  1953. tmpKey.coefficient.data = coefficient->attrib.pValue;
  1954. tmpKey.coefficient.len = coefficient->attrib.ulValueLen;
  1955. }
  1956. if (fillIfNeeded) {
  1957. /*
  1958. * populate requires one exponent plus 2 other components to work.
  1959. * we expected our caller to check that first. If that didn't happen,
  1960. * populate will simply return an error here.
  1961. */
  1962. rv = RSA_PopulatePrivateKey(&tmpKey);
  1963. if (rv != SECSuccess) {
  1964. goto loser;
  1965. }
  1966. }
  1967. rv = RSA_PrivateKeyCheck(&tmpKey);
  1968. if (rv != SECSuccess) {
  1969. goto loser;
  1970. }
  1971. /* now that we have a fully populated key, set all our attribute values */
  1972. rv = SECFailure;
  1973. if (!modulus || modulus->attrib.pValue != tmpKey.modulus.data) {
  1974. crv = sftk_forceAttribute(object, CKA_MODULUS,
  1975. sftk_item_expand(&tmpKey.modulus));
  1976. if (crv != CKR_OK)
  1977. goto loser;
  1978. }
  1979. if (!publicExponent ||
  1980. publicExponent->attrib.pValue != tmpKey.publicExponent.data) {
  1981. crv = sftk_forceAttribute(object, CKA_PUBLIC_EXPONENT,
  1982. sftk_item_expand(&tmpKey.publicExponent));
  1983. if (crv != CKR_OK)
  1984. goto loser;
  1985. }
  1986. if (!privateExponent ||
  1987. privateExponent->attrib.pValue != tmpKey.privateExponent.data) {
  1988. crv = sftk_forceAttribute(object, CKA_PRIVATE_EXPONENT,
  1989. sftk_item_expand(&tmpKey.privateExponent));
  1990. if (crv != CKR_OK)
  1991. goto loser;
  1992. }
  1993. if (!prime1 || prime1->attrib.pValue != tmpKey.prime1.data) {
  1994. crv = sftk_forceAttribute(object, CKA_PRIME_1,
  1995. sftk_item_expand(&tmpKey.prime1));
  1996. if (crv != CKR_OK)
  1997. goto loser;
  1998. }
  1999. if (!prime2 || prime2->attrib.pValue != tmpKey.prime2.data) {
  2000. crv = sftk_forceAttribute(object, CKA_PRIME_2,
  2001. sftk_item_expand(&tmpKey.prime2));
  2002. if (crv != CKR_OK)
  2003. goto loser;
  2004. }
  2005. if (!exponent1 || exponent1->attrib.pValue != tmpKey.exponent1.data) {
  2006. crv = sftk_forceAttribute(object, CKA_EXPONENT_1,
  2007. sftk_item_expand(&tmpKey.exponent1));
  2008. if (crv != CKR_OK)
  2009. goto loser;
  2010. }
  2011. if (!exponent2 || exponent2->attrib.pValue != tmpKey.exponent2.data) {
  2012. crv = sftk_forceAttribute(object, CKA_EXPONENT_2,
  2013. sftk_item_expand(&tmpKey.exponent2));
  2014. if (crv != CKR_OK)
  2015. goto loser;
  2016. }
  2017. if (!coefficient || coefficient->attrib.pValue != tmpKey.coefficient.data) {
  2018. crv = sftk_forceAttribute(object, CKA_COEFFICIENT,
  2019. sftk_item_expand(&tmpKey.coefficient));
  2020. if (crv != CKR_OK)
  2021. goto loser;
  2022. }
  2023. rv = SECSuccess;
  2024. /* we're done (one way or the other), clean up all our stuff */
  2025. loser:
  2026. if (tmpKey.arena) {
  2027. PORT_FreeArena(tmpKey.arena, PR_TRUE);
  2028. }
  2029. if (modulus) {
  2030. sftk_FreeAttribute(modulus);
  2031. }
  2032. if (prime1) {
  2033. sftk_FreeAttribute(prime1);
  2034. }
  2035. if (prime2) {
  2036. sftk_FreeAttribute(prime2);
  2037. }
  2038. if (privateExponent) {
  2039. sftk_FreeAttribute(privateExponent);
  2040. }
  2041. if (publicExponent) {
  2042. sftk_FreeAttribute(publicExponent);
  2043. }
  2044. if (exponent1) {
  2045. sftk_FreeAttribute(exponent1);
  2046. }
  2047. if (exponent2) {
  2048. sftk_FreeAttribute(exponent2);
  2049. }
  2050. if (coefficient) {
  2051. sftk_FreeAttribute(coefficient);
  2052. }
  2053. return rv;
  2054. }
  2055. /* Generate a low private key structure from an object */
  2056. NSSLOWKEYPrivateKey *
  2057. sftk_GetPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
  2058. {
  2059. NSSLOWKEYPrivateKey *priv = NULL;
  2060. if (object->objclass != CKO_PRIVATE_KEY) {
  2061. *crvp = CKR_KEY_TYPE_INCONSISTENT;
  2062. return NULL;
  2063. }
  2064. if (object->objectInfo) {
  2065. *crvp = CKR_OK;
  2066. return (NSSLOWKEYPrivateKey *)object->objectInfo;
  2067. }
  2068. priv = sftk_mkPrivKey(object, key_type, crvp);
  2069. object->objectInfo = priv;
  2070. object->infoFree = (SFTKFree)nsslowkey_DestroyPrivateKey;
  2071. return priv;
  2072. }
  2073. /* populate a public key object from a lowpublic keys structure */
  2074. CK_RV
  2075. sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType, NSSLOWKEYPublicKey *pubKey)
  2076. {
  2077. CK_OBJECT_CLASS classType = CKO_PUBLIC_KEY;
  2078. CK_BBOOL cktrue = CK_TRUE;
  2079. CK_RV crv = CKR_OK;
  2080. sftk_DeleteAttributeType(publicKey, CKA_CLASS);
  2081. sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE);
  2082. sftk_DeleteAttributeType(publicKey, CKA_VALUE);
  2083. switch (keyType) {
  2084. case CKK_RSA:
  2085. sftk_DeleteAttributeType(publicKey, CKA_MODULUS);
  2086. sftk_DeleteAttributeType(publicKey, CKA_PUBLIC_EXPONENT);
  2087. /* format the keys */
  2088. /* fill in the RSA dependent paramenters in the public key */
  2089. crv = sftk_AddAttributeType(publicKey, CKA_MODULUS,
  2090. sftk_item_expand(&pubKey->u.rsa.modulus));
  2091. if (crv != CKR_OK) {
  2092. break;
  2093. }
  2094. crv = sftk_AddAttributeType(publicKey, CKA_PUBLIC_EXPONENT,
  2095. sftk_item_expand(&pubKey->u.rsa.publicExponent));
  2096. break;
  2097. case CKK_DSA:
  2098. sftk_DeleteAttributeType(publicKey, CKA_PRIME);
  2099. sftk_DeleteAttributeType(publicKey, CKA_SUBPRIME);
  2100. sftk_DeleteAttributeType(publicKey, CKA_BASE);
  2101. crv = sftk_AddAttributeType(publicKey, CKA_PRIME,
  2102. sftk_item_expand(&pubKey->u.dsa.params.prime));
  2103. if (crv != CKR_OK) {
  2104. break;
  2105. }
  2106. crv = sftk_AddAttributeType(publicKey, CKA_SUBPRIME,
  2107. sftk_item_expand(&pubKey->u.dsa.params.subPrime));
  2108. if (crv != CKR_OK) {
  2109. break;
  2110. }
  2111. crv = sftk_AddAttributeType(publicKey, CKA_BASE,
  2112. sftk_item_expand(&pubKey->u.dsa.params.base));
  2113. if (crv != CKR_OK) {
  2114. break;
  2115. }
  2116. crv = sftk_AddAttributeType(publicKey, CKA_VALUE,
  2117. sftk_item_expand(&pubKey->u.dsa.publicValue));
  2118. break;
  2119. case CKK_DH:
  2120. sftk_DeleteAttributeType(publicKey, CKA_PRIME);
  2121. sftk_DeleteAttributeType(publicKey, CKA_BASE);
  2122. crv = sftk_AddAttributeType(publicKey, CKA_PRIME,
  2123. sftk_item_expand(&pubKey->u.dh.prime));
  2124. if (crv != CKR_OK) {
  2125. break;
  2126. }
  2127. crv = sftk_AddAttributeType(publicKey, CKA_BASE,
  2128. sftk_item_expand(&pubKey->u.dh.base));
  2129. if (crv != CKR_OK) {
  2130. break;
  2131. }
  2132. crv = sftk_AddAttributeType(publicKey, CKA_VALUE,
  2133. sftk_item_expand(&pubKey->u.dh.publicValue));
  2134. break;
  2135. case CKK_EC:
  2136. sftk_DeleteAttributeType(publicKey, CKA_EC_PARAMS);
  2137. sftk_DeleteAttributeType(publicKey, CKA_EC_POINT);
  2138. crv = sftk_AddAttributeType(publicKey, CKA_EC_PARAMS,
  2139. sftk_item_expand(&pubKey->u.ec.ecParams.DEREncoding));
  2140. if (crv != CKR_OK) {
  2141. break;
  2142. }
  2143. crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
  2144. sftk_item_expand(&pubKey->u.ec.publicValue));
  2145. break;
  2146. default:
  2147. return CKR_KEY_TYPE_INCONSISTENT;
  2148. }
  2149. if (crv != CKR_OK) {
  2150. return crv;
  2151. }
  2152. crv = sftk_AddAttributeType(publicKey, CKA_CLASS, &classType,
  2153. sizeof(CK_OBJECT_CLASS));
  2154. if (crv != CKR_OK) {
  2155. return crv;
  2156. }
  2157. crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE, &keyType,
  2158. sizeof(CK_KEY_TYPE));
  2159. if (crv != CKR_OK) {
  2160. return crv;
  2161. }
  2162. /* now handle the operator attributes */
  2163. if (sftk_isTrue(privateKey, CKA_DECRYPT)) {
  2164. crv = sftk_forceAttribute(publicKey, CKA_ENCRYPT, &cktrue, sizeof(CK_BBOOL));
  2165. if (crv != CKR_OK) {
  2166. return crv;
  2167. }
  2168. }
  2169. if (sftk_isTrue(privateKey, CKA_SIGN)) {
  2170. crv = sftk_forceAttribute(publicKey, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));
  2171. if (crv != CKR_OK) {
  2172. return crv;
  2173. }
  2174. }
  2175. if (sftk_isTrue(privateKey, CKA_SIGN_RECOVER)) {
  2176. crv = sftk_forceAttribute(publicKey, CKA_VERIFY_RECOVER, &cktrue, sizeof(CK_BBOOL));
  2177. if (crv != CKR_OK) {
  2178. return crv;
  2179. }
  2180. }
  2181. if (sftk_isTrue(privateKey, CKA_DERIVE)) {
  2182. crv = sftk_forceAttribute(publicKey, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
  2183. if (crv != CKR_OK) {
  2184. return crv;
  2185. }
  2186. }
  2187. return crv;
  2188. }
  2189. /*
  2190. **************************** Symetric Key utils ************************
  2191. */
  2192. /*
  2193. * set the DES key with parity bits correctly
  2194. */
  2195. void
  2196. sftk_FormatDESKey(unsigned char *key, int length)
  2197. {
  2198. int i;
  2199. /* format the des key */
  2200. for (i = 0; i < length; i++) {
  2201. key[i] = parityTable[key[i] >> 1];
  2202. }
  2203. }
  2204. /*
  2205. * check a des key (des2 or des3 subkey) for weak keys.
  2206. */
  2207. PRBool
  2208. sftk_CheckDESKey(unsigned char *key)
  2209. {
  2210. int i;
  2211. /* format the des key with parity */
  2212. sftk_FormatDESKey(key, 8);
  2213. for (i = 0; i < sftk_desWeakTableSize; i++) {
  2214. if (PORT_Memcmp(key, sftk_desWeakTable[i], 8) == 0) {
  2215. return PR_TRUE;
  2216. }
  2217. }
  2218. return PR_FALSE;
  2219. }
  2220. /*
  2221. * check if a des or triple des key is weak.
  2222. */
  2223. PRBool
  2224. sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type)
  2225. {
  2226. switch (key_type) {
  2227. case CKK_DES:
  2228. return sftk_CheckDESKey(key);
  2229. case CKM_DES2_KEY_GEN:
  2230. if (sftk_CheckDESKey(key))
  2231. return PR_TRUE;
  2232. return sftk_CheckDESKey(&key[8]);
  2233. case CKM_DES3_KEY_GEN:
  2234. if (sftk_CheckDESKey(key))
  2235. return PR_TRUE;
  2236. if (sftk_CheckDESKey(&key[8]))
  2237. return PR_TRUE;
  2238. return sftk_CheckDESKey(&key[16]);
  2239. default:
  2240. break;
  2241. }
  2242. return PR_FALSE;
  2243. }
  2244. /**********************************************************************
  2245. *
  2246. * Start of PKCS 11 functions
  2247. *
  2248. **********************************************************************/
  2249. /* return the function list */
  2250. CK_RV
  2251. NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
  2252. {
  2253. *pFunctionList = (CK_FUNCTION_LIST_PTR)&sftk_funcList_v2;
  2254. return CKR_OK;
  2255. }
  2256. /* return the function list */
  2257. CK_RV
  2258. C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
  2259. {
  2260. return NSC_GetFunctionList(pFunctionList);
  2261. }
  2262. CK_RV
  2263. NSC_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount)
  2264. {
  2265. CK_ULONG count = *pulCount;
  2266. *pulCount = NSS_INTERFACE_COUNT;
  2267. if (interfaces == NULL) {
  2268. return CKR_OK;
  2269. }
  2270. if (count < NSS_INTERFACE_COUNT) {
  2271. return CKR_BUFFER_TOO_SMALL;
  2272. }
  2273. PORT_Memcpy(interfaces, nss_interfaces, sizeof(nss_interfaces));
  2274. return CKR_OK;
  2275. }
  2276. CK_RV
  2277. C_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount)
  2278. {
  2279. return NSC_GetInterfaceList(interfaces, pulCount);
  2280. }
  2281. /*
  2282. * Get the requested interface, use the nss_interfaces array so we can
  2283. * easily add new interfaces as they occur.
  2284. */
  2285. CK_RV
  2286. NSC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion,
  2287. CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags)
  2288. {
  2289. int i;
  2290. for (i = 0; i < NSS_INTERFACE_COUNT; i++) {
  2291. CK_INTERFACE_PTR interface = &nss_interfaces[i];
  2292. if (pInterfaceName && PORT_Strcmp((char *)pInterfaceName, (char *)interface->pInterfaceName) != 0) {
  2293. continue;
  2294. }
  2295. if (pVersion && PORT_Memcmp(pVersion, (CK_VERSION *)interface->pFunctionList, sizeof(CK_VERSION)) != 0) {
  2296. continue;
  2297. }
  2298. if (flags & ((interface->flags & flags) != flags)) {
  2299. continue;
  2300. }
  2301. *ppInterface = interface;
  2302. return CKR_OK;
  2303. }
  2304. return CKR_ARGUMENTS_BAD;
  2305. }
  2306. CK_RV
  2307. C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion,
  2308. CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags)
  2309. {
  2310. return NSC_GetInterface(pInterfaceName, pVersion, ppInterface, flags);
  2311. }
  2312. static PLHashNumber
  2313. sftk_HashNumber(const void *key)
  2314. {
  2315. return (PLHashNumber)((char *)key - (char *)NULL);
  2316. }
  2317. /*
  2318. * eventually I'd like to expunge all occurances of XXX_SLOT_ID and
  2319. * just go with the info in the slot. This is one place, however,
  2320. * where it might be a little difficult.
  2321. */
  2322. const char *
  2323. sftk_getDefTokName(CK_SLOT_ID slotID)
  2324. {
  2325. static char buf[33];
  2326. switch (slotID) {
  2327. case NETSCAPE_SLOT_ID:
  2328. return "NSS Generic Crypto Services ";
  2329. case PRIVATE_KEY_SLOT_ID:
  2330. return "NSS Certificate DB ";
  2331. case FIPS_SLOT_ID:
  2332. return "NSS FIPS 140-2 Certificate DB ";
  2333. default:
  2334. break;
  2335. }
  2336. sprintf(buf, "NSS Application Token %08x ", (unsigned int)slotID);
  2337. return buf;
  2338. }
  2339. const char *
  2340. sftk_getDefSlotName(CK_SLOT_ID slotID)
  2341. {
  2342. static char buf[65];
  2343. switch (slotID) {
  2344. case NETSCAPE_SLOT_ID:
  2345. return "NSS Internal Cryptographic Services ";
  2346. case PRIVATE_KEY_SLOT_ID:
  2347. return "NSS User Private Key and Certificate Services ";
  2348. case FIPS_SLOT_ID:
  2349. return "NSS FIPS 140-2 User Private Key Services ";
  2350. default:
  2351. break;
  2352. }
  2353. sprintf(buf,
  2354. "NSS Application Slot %08x ",
  2355. (unsigned int)slotID);
  2356. return buf;
  2357. }
  2358. static CK_ULONG nscSlotCount[2] = { 0, 0 };
  2359. static CK_SLOT_ID_PTR nscSlotList[2] = { NULL, NULL };
  2360. static CK_ULONG nscSlotListSize[2] = { 0, 0 };
  2361. static PLHashTable *nscSlotHashTable[2] = { NULL, NULL };
  2362. static unsigned int
  2363. sftk_GetModuleIndex(CK_SLOT_ID slotID)
  2364. {
  2365. if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
  2366. return NSC_FIPS_MODULE;
  2367. }
  2368. return NSC_NON_FIPS_MODULE;
  2369. }
  2370. /* look up a slot structure from the ID (used to be a macro when we only
  2371. * had two slots) */
  2372. /* if all is true, return the slot even if it has been 'unloaded' */
  2373. /* if all is false, only return the slots which are present */
  2374. SFTKSlot *
  2375. sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all)
  2376. {
  2377. SFTKSlot *slot;
  2378. int index = sftk_GetModuleIndex(slotID);
  2379. if (nscSlotHashTable[index] == NULL)
  2380. return NULL;
  2381. slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index],
  2382. (void *)slotID);
  2383. /* cleared slots shouldn't 'show up' */
  2384. if (slot && !all && !slot->present)
  2385. slot = NULL;
  2386. return slot;
  2387. }
  2388. CK_SLOT_ID
  2389. sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle)
  2390. {
  2391. CK_ULONG slotIDIndex = (handle >> 24) & 0x7f;
  2392. CK_ULONG moduleIndex = (handle >> 31) & 1;
  2393. if (slotIDIndex >= nscSlotCount[moduleIndex]) {
  2394. return (CK_SLOT_ID)-1;
  2395. }
  2396. return nscSlotList[moduleIndex][slotIDIndex];
  2397. }
  2398. SFTKSlot *
  2399. sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
  2400. {
  2401. return sftk_SlotFromID(sftk_SlotIDFromSessionHandle(handle), PR_FALSE);
  2402. }
  2403. static CK_RV
  2404. sftk_RegisterSlot(SFTKSlot *slot, int moduleIndex)
  2405. {
  2406. PLHashEntry *entry;
  2407. unsigned int index;
  2408. index = sftk_GetModuleIndex(slot->slotID);
  2409. /* make sure the slotID for this module is valid */
  2410. if (moduleIndex != index) {
  2411. return CKR_SLOT_ID_INVALID;
  2412. }
  2413. if (nscSlotList[index] == NULL) {
  2414. nscSlotListSize[index] = NSC_SLOT_LIST_BLOCK_SIZE;
  2415. nscSlotList[index] = (CK_SLOT_ID *)
  2416. PORT_ZAlloc(nscSlotListSize[index] * sizeof(CK_SLOT_ID));
  2417. if (nscSlotList[index] == NULL) {
  2418. return CKR_HOST_MEMORY;
  2419. }
  2420. }
  2421. if (nscSlotCount[index] >= nscSlotListSize[index]) {
  2422. CK_SLOT_ID *oldNscSlotList = nscSlotList[index];
  2423. CK_ULONG oldNscSlotListSize = nscSlotListSize[index];
  2424. nscSlotListSize[index] += NSC_SLOT_LIST_BLOCK_SIZE;
  2425. nscSlotList[index] = (CK_SLOT_ID *)PORT_Realloc(oldNscSlotList,
  2426. nscSlotListSize[index] * sizeof(CK_SLOT_ID));
  2427. if (nscSlotList[index] == NULL) {
  2428. nscSlotList[index] = oldNscSlotList;
  2429. nscSlotListSize[index] = oldNscSlotListSize;
  2430. return CKR_HOST_MEMORY;
  2431. }
  2432. }
  2433. if (nscSlotHashTable[index] == NULL) {
  2434. nscSlotHashTable[index] = PL_NewHashTable(64, sftk_HashNumber,
  2435. PL_CompareValues, PL_CompareValues, NULL, 0);
  2436. if (nscSlotHashTable[index] == NULL) {
  2437. return CKR_HOST_MEMORY;
  2438. }
  2439. }
  2440. entry = PL_HashTableAdd(nscSlotHashTable[index], (void *)slot->slotID, slot);
  2441. if (entry == NULL) {
  2442. return CKR_HOST_MEMORY;
  2443. }
  2444. slot->index = (nscSlotCount[index] & 0x7f) | ((index << 7) & 0x80);
  2445. nscSlotList[index][nscSlotCount[index]++] = slot->slotID;
  2446. return CKR_OK;
  2447. }
  2448. /*
  2449. * ths function has all the common initialization that happens whenever we
  2450. * create a new slot or repurpose an old slot (only valid for slotID's 4
  2451. * and greater).
  2452. *
  2453. * things that are not reinitialized are:
  2454. * slotID (can't change)
  2455. * slotDescription (can't change once defined)
  2456. * the locks and hash tables (difficult to change in running code, and
  2457. * unnecessary. hash tables and list are cleared on shutdown, but they
  2458. * are cleared in a 'friendly' way).
  2459. * session and object ID counters -- so any old sessions and objects in the
  2460. * application will get properly notified that the world has changed.
  2461. *
  2462. * things that are reinitialized:
  2463. * database (otherwise what would the point be;).
  2464. * state variables related to databases.
  2465. * session count stat info.
  2466. * tokenDescription.
  2467. *
  2468. * NOTE: slotID's 4 and greater show up as removable devices.
  2469. *
  2470. */
  2471. CK_RV
  2472. SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir,
  2473. char *updateID, sftk_token_parameters *params, int moduleIndex)
  2474. {
  2475. PRBool needLogin = !params->noKeyDB;
  2476. CK_RV crv;
  2477. slot->hasTokens = PR_FALSE;
  2478. slot->sessionIDConflict = 0;
  2479. slot->sessionCount = 0;
  2480. slot->rwSessionCount = 0;
  2481. slot->needLogin = PR_FALSE;
  2482. slot->isLoggedIn = PR_FALSE;
  2483. slot->ssoLoggedIn = PR_FALSE;
  2484. slot->DB_loaded = PR_FALSE;
  2485. slot->certDB = NULL;
  2486. slot->keyDB = NULL;
  2487. slot->minimumPinLen = 0;
  2488. slot->readOnly = params->readOnly;
  2489. sftk_setStringName(params->tokdes ? params->tokdes : sftk_getDefTokName(slot->slotID), slot->tokDescription,
  2490. sizeof(slot->tokDescription), PR_TRUE);
  2491. sftk_setStringName(params->updtokdes ? params->updtokdes : " ",
  2492. slot->updateTokDescription,
  2493. sizeof(slot->updateTokDescription), PR_TRUE);
  2494. if ((!params->noCertDB) || (!params->noKeyDB)) {
  2495. SFTKDBHandle *certHandle = NULL;
  2496. SFTKDBHandle *keyHandle = NULL;
  2497. crv = sftk_DBInit(params->configdir ? params->configdir : configdir,
  2498. params->certPrefix, params->keyPrefix,
  2499. params->updatedir ? params->updatedir : updatedir,
  2500. params->updCertPrefix, params->updKeyPrefix,
  2501. params->updateID ? params->updateID : updateID,
  2502. params->readOnly, params->noCertDB, params->noKeyDB,
  2503. params->forceOpen,
  2504. moduleIndex == NSC_FIPS_MODULE,
  2505. &certHandle, &keyHandle);
  2506. if (crv != CKR_OK) {
  2507. goto loser;
  2508. }
  2509. slot->certDB = certHandle;
  2510. slot->keyDB = keyHandle;
  2511. }
  2512. if (needLogin) {
  2513. /* if the data base is initialized with a null password,remember that */
  2514. slot->needLogin =
  2515. (PRBool)!sftk_hasNullPassword(slot, slot->keyDB);
  2516. if ((params->minPW >= 0) && (params->minPW <= SFTK_MAX_PIN)) {
  2517. slot->minimumPinLen = params->minPW;
  2518. }
  2519. if ((slot->minimumPinLen == 0) && (params->pwRequired)) {
  2520. slot->minimumPinLen = 1;
  2521. }
  2522. /* Make sure the pin len is set to the Minimum allowed value for fips
  2523. * when in FIPS mode. NOTE: we don't set it if the database has not
  2524. * been initialized yet so that we can init into level1 mode if needed
  2525. */
  2526. if ((sftkdb_HasPasswordSet(slot->keyDB) == SECSuccess) &&
  2527. (moduleIndex == NSC_FIPS_MODULE) &&
  2528. (slot->minimumPinLen < FIPS_MIN_PIN)) {
  2529. slot->minimumPinLen = FIPS_MIN_PIN;
  2530. }
  2531. }
  2532. slot->present = PR_TRUE;
  2533. return CKR_OK;
  2534. loser:
  2535. SFTK_ShutdownSlot(slot);
  2536. return crv;
  2537. }
  2538. /*
  2539. * initialize one of the slot structures. figure out which by the ID
  2540. */
  2541. CK_RV
  2542. SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
  2543. sftk_token_parameters *params, int moduleIndex)
  2544. {
  2545. unsigned int i;
  2546. CK_SLOT_ID slotID = params->slotID;
  2547. SFTKSlot *slot;
  2548. CK_RV crv = CKR_HOST_MEMORY;
  2549. /*
  2550. * first we initialize everything that is 'permanent' with this slot.
  2551. * that is everything we aren't going to shutdown if we close this slot
  2552. * and open it up again with different databases */
  2553. slot = PORT_ZNew(SFTKSlot);
  2554. if (slot == NULL) {
  2555. return CKR_HOST_MEMORY;
  2556. }
  2557. slot->optimizeSpace = params->optimizeSpace;
  2558. if (slot->optimizeSpace) {
  2559. slot->sessObjHashSize = SPACE_SESSION_OBJECT_HASH_SIZE;
  2560. slot->sessHashSize = SPACE_SESSION_HASH_SIZE;
  2561. slot->numSessionLocks = 1;
  2562. } else {
  2563. slot->sessObjHashSize = TIME_SESSION_OBJECT_HASH_SIZE;
  2564. slot->sessHashSize = TIME_SESSION_HASH_SIZE;
  2565. slot->numSessionLocks = slot->sessHashSize / BUCKETS_PER_SESSION_LOCK;
  2566. }
  2567. slot->sessionLockMask = slot->numSessionLocks - 1;
  2568. slot->slotLock = PZ_NewLock(nssILockSession);
  2569. if (slot->slotLock == NULL)
  2570. goto mem_loser;
  2571. slot->sessionLock = PORT_ZNewArray(PZLock *, slot->numSessionLocks);
  2572. if (slot->sessionLock == NULL)
  2573. goto mem_loser;
  2574. for (i = 0; i < slot->numSessionLocks; i++) {
  2575. slot->sessionLock[i] = PZ_NewLock(nssILockSession);
  2576. if (slot->sessionLock[i] == NULL)
  2577. goto mem_loser;
  2578. }
  2579. slot->objectLock = PZ_NewLock(nssILockObject);
  2580. if (slot->objectLock == NULL)
  2581. goto mem_loser;
  2582. slot->pwCheckLock = PR_NewLock();
  2583. if (slot->pwCheckLock == NULL)
  2584. goto mem_loser;
  2585. slot->head = PORT_ZNewArray(SFTKSession *, slot->sessHashSize);
  2586. if (slot->head == NULL)
  2587. goto mem_loser;
  2588. slot->sessObjHashTable = PORT_ZNewArray(SFTKObject *, slot->sessObjHashSize);
  2589. if (slot->sessObjHashTable == NULL)
  2590. goto mem_loser;
  2591. slot->tokObjHashTable = PL_NewHashTable(64, sftk_HashNumber, PL_CompareValues,
  2592. SECITEM_HashCompare, NULL, 0);
  2593. if (slot->tokObjHashTable == NULL)
  2594. goto mem_loser;
  2595. slot->sessionIDCount = 0;
  2596. slot->sessionObjectHandleCount = minSessionObjectHandle;
  2597. slot->slotID = slotID;
  2598. sftk_setStringName(params->slotdes ? params->slotdes : sftk_getDefSlotName(slotID), slot->slotDescription,
  2599. sizeof(slot->slotDescription), PR_TRUE);
  2600. /* call the reinit code to set everything that changes between token
  2601. * init calls */
  2602. crv = SFTK_SlotReInit(slot, configdir, updatedir, updateID,
  2603. params, moduleIndex);
  2604. if (crv != CKR_OK) {
  2605. goto loser;
  2606. }
  2607. crv = sftk_RegisterSlot(slot, moduleIndex);
  2608. if (crv != CKR_OK) {
  2609. goto loser;
  2610. }
  2611. return CKR_OK;
  2612. mem_loser:
  2613. crv = CKR_HOST_MEMORY;
  2614. loser:
  2615. SFTK_DestroySlotData(slot);
  2616. return crv;
  2617. }
  2618. CK_RV
  2619. sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout)
  2620. {
  2621. SFTKSession *session;
  2622. unsigned int i;
  2623. SFTKDBHandle *handle;
  2624. /* first log out the card */
  2625. /* special case - if we are in a middle of upgrade, we want to close the
  2626. * sessions to fake a token removal to tell the upper level code we have
  2627. * switched from one database to another, but we don't want to
  2628. * explicity logout in case we can continue the upgrade with the
  2629. * existing password if possible.
  2630. */
  2631. if (logout) {
  2632. handle = sftk_getKeyDB(slot);
  2633. SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
  2634. slot->isLoggedIn = PR_FALSE;
  2635. if (slot->needLogin && handle) {
  2636. sftkdb_ClearPassword(handle);
  2637. }
  2638. SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
  2639. if (handle) {
  2640. sftk_freeDB(handle);
  2641. }
  2642. }
  2643. /* now close all the current sessions */
  2644. /* NOTE: If you try to open new sessions before NSC_CloseAllSessions
  2645. * completes, some of those new sessions may or may not be closed by
  2646. * NSC_CloseAllSessions... but any session running when this code starts
  2647. * will guarrenteed be close, and no session will be partially closed */
  2648. for (i = 0; i < slot->sessHashSize; i++) {
  2649. PZLock *lock = SFTK_SESSION_LOCK(slot, i);
  2650. do {
  2651. SKIP_AFTER_FORK(PZ_Lock(lock));
  2652. session = slot->head[i];
  2653. /* hand deque */
  2654. /* this duplicates function of NSC_close session functions, but
  2655. * because we know that we are freeing all the sessions, we can
  2656. * do more efficient processing */
  2657. if (session) {
  2658. slot->head[i] = session->next;
  2659. if (session->next)
  2660. session->next->prev = NULL;
  2661. session->next = session->prev = NULL;
  2662. SKIP_AFTER_FORK(PZ_Unlock(lock));
  2663. SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
  2664. --slot->sessionCount;
  2665. SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
  2666. if (session->info.flags & CKF_RW_SESSION) {
  2667. (void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
  2668. }
  2669. } else {
  2670. SKIP_AFTER_FORK(PZ_Unlock(lock));
  2671. }
  2672. if (session) {
  2673. sftk_DestroySession(session);
  2674. }
  2675. } while (session != NULL);
  2676. }
  2677. return CKR_OK;
  2678. }
  2679. /*
  2680. * shut down the databases.
  2681. * we get the slot lock (which also protects slot->certDB and slot->keyDB)
  2682. * and clear the values so the new users will not find the databases.
  2683. * once things are clear, we can release our references to the databases.
  2684. * The databases will close when the last reference is released.
  2685. *
  2686. * We use reference counts so that we don't crash if someone shuts down
  2687. * a token that another thread is actively using.
  2688. */
  2689. static void
  2690. sftk_DBShutdown(SFTKSlot *slot)
  2691. {
  2692. SFTKDBHandle *certHandle;
  2693. SFTKDBHandle *keyHandle;
  2694. SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
  2695. certHandle = slot->certDB;
  2696. slot->certDB = NULL;
  2697. keyHandle = slot->keyDB;
  2698. slot->keyDB = NULL;
  2699. SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
  2700. if (certHandle) {
  2701. sftk_freeDB(certHandle);
  2702. }
  2703. if (keyHandle) {
  2704. sftk_freeDB(keyHandle);
  2705. }
  2706. }
  2707. CK_RV
  2708. SFTK_ShutdownSlot(SFTKSlot *slot)
  2709. {
  2710. /* make sure no new PK11 calls work except C_GetSlotInfo */
  2711. slot->present = PR_FALSE;
  2712. /* close all outstanding sessions
  2713. * the sessHashSize variable guarentees we have all the session
  2714. * mechanism set up */
  2715. if (slot->head) {
  2716. sftk_CloseAllSessions(slot, PR_TRUE);
  2717. }
  2718. /* clear all objects.. session objects are cleared as a result of
  2719. * closing all the sessions. We just need to clear the token object
  2720. * cache. slot->tokObjHashTable guarentees we have the token
  2721. * infrastructure set up. */
  2722. if (slot->tokObjHashTable) {
  2723. SFTK_ClearTokenKeyHashTable(slot);
  2724. }
  2725. /* clear the slot description for the next guy */
  2726. PORT_Memset(slot->tokDescription, 0, sizeof(slot->tokDescription));
  2727. /* now shut down the databases. */
  2728. sftk_DBShutdown(slot);
  2729. return CKR_OK;
  2730. }
  2731. /*
  2732. * initialize one of the slot structures. figure out which by the ID
  2733. */
  2734. CK_RV
  2735. SFTK_DestroySlotData(SFTKSlot *slot)
  2736. {
  2737. unsigned int i;
  2738. SFTK_ShutdownSlot(slot);
  2739. if (slot->tokObjHashTable) {
  2740. PL_HashTableDestroy(slot->tokObjHashTable);
  2741. slot->tokObjHashTable = NULL;
  2742. }
  2743. if (slot->sessObjHashTable) {
  2744. PORT_Free(slot->sessObjHashTable);
  2745. slot->sessObjHashTable = NULL;
  2746. }
  2747. slot->sessObjHashSize = 0;
  2748. if (slot->head) {
  2749. PORT_Free(slot->head);
  2750. slot->head = NULL;
  2751. }
  2752. slot->sessHashSize = 0;
  2753. /* OK everything has been disassembled, now we can finally get rid
  2754. * of the locks */
  2755. SKIP_AFTER_FORK(PZ_DestroyLock(slot->slotLock));
  2756. slot->slotLock = NULL;
  2757. if (slot->sessionLock) {
  2758. for (i = 0; i < slot->numSessionLocks; i++) {
  2759. if (slot->sessionLock[i]) {
  2760. SKIP_AFTER_FORK(PZ_DestroyLock(slot->sessionLock[i]));
  2761. slot->sessionLock[i] = NULL;
  2762. }
  2763. }
  2764. PORT_Free(slot->sessionLock);
  2765. slot->sessionLock = NULL;
  2766. }
  2767. if (slot->objectLock) {
  2768. SKIP_AFTER_FORK(PZ_DestroyLock(slot->objectLock));
  2769. slot->objectLock = NULL;
  2770. }
  2771. if (slot->pwCheckLock) {
  2772. SKIP_AFTER_FORK(PR_DestroyLock(slot->pwCheckLock));
  2773. slot->pwCheckLock = NULL;
  2774. }
  2775. PORT_Free(slot);
  2776. return CKR_OK;
  2777. }
  2778. /*
  2779. * handle the SECMOD.db
  2780. */
  2781. char **
  2782. NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args)
  2783. {
  2784. #ifndef NSS_DISABLE_DBM
  2785. char *secmod = NULL;
  2786. char *appName = NULL;
  2787. char *filename = NULL;
  2788. NSSDBType dbType = NSS_DB_TYPE_NONE;
  2789. PRBool rw;
  2790. static char *success = "Success";
  2791. #endif /* NSS_DISABLE_DBM */
  2792. char **rvstr = NULL;
  2793. rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
  2794. if (rvstr != NULL) {
  2795. return rvstr;
  2796. }
  2797. if (PORT_GetError() != SEC_ERROR_LEGACY_DATABASE) {
  2798. return NULL;
  2799. }
  2800. #ifndef NSS_DISABLE_DBM
  2801. /* The legacy database uses the old dbm, which is only linked with the
  2802. * legacy DB handler, which is only callable from softoken */
  2803. secmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &appName,
  2804. &filename, &rw);
  2805. switch (function) {
  2806. case SECMOD_MODULE_DB_FUNCTION_FIND:
  2807. if (secmod == NULL) {
  2808. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  2809. goto loser;
  2810. }
  2811. if (rw && (dbType != NSS_DB_TYPE_LEGACY) &&
  2812. (dbType != NSS_DB_TYPE_MULTIACCESS)) {
  2813. /* if we get here, we are trying to update the local database */
  2814. /* force data from the legacy DB */
  2815. char *oldSecmod = NULL;
  2816. char *oldAppName = NULL;
  2817. char *oldFilename = NULL;
  2818. PRBool oldrw;
  2819. char **strings = NULL;
  2820. int i;
  2821. dbType = NSS_DB_TYPE_LEGACY;
  2822. oldSecmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &oldAppName,
  2823. &oldFilename, &oldrw);
  2824. strings = sftkdbCall_ReadSecmodDB(appName, oldFilename, oldSecmod,
  2825. (char *)parameters, oldrw);
  2826. if (strings) {
  2827. /* write out the strings */
  2828. for (i = 0; strings[i]; i++) {
  2829. NSSUTIL_DoModuleDBFunction(SECMOD_MODULE_DB_FUNCTION_ADD,
  2830. parameters, strings[i]);
  2831. }
  2832. sftkdbCall_ReleaseSecmodDBData(oldAppName, oldFilename, oldSecmod,
  2833. (char **)strings, oldrw);
  2834. } else {
  2835. /* write out a dummy record */
  2836. NSSUTIL_DoModuleDBFunction(SECMOD_MODULE_DB_FUNCTION_ADD,
  2837. parameters, " ");
  2838. }
  2839. if (oldSecmod) {
  2840. PR_smprintf_free(oldSecmod);
  2841. }
  2842. if (oldAppName) {
  2843. PORT_Free(oldAppName);
  2844. }
  2845. if (oldFilename) {
  2846. PORT_Free(oldFilename);
  2847. }
  2848. rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
  2849. break;
  2850. }
  2851. rvstr = sftkdbCall_ReadSecmodDB(appName, filename, secmod,
  2852. (char *)parameters, rw);
  2853. break;
  2854. case SECMOD_MODULE_DB_FUNCTION_ADD:
  2855. if (secmod == NULL) {
  2856. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  2857. goto loser;
  2858. }
  2859. rvstr = (sftkdbCall_AddSecmodDB(appName, filename, secmod,
  2860. (char *)args, rw) == SECSuccess)
  2861. ? &success
  2862. : NULL;
  2863. break;
  2864. case SECMOD_MODULE_DB_FUNCTION_DEL:
  2865. if (secmod == NULL) {
  2866. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  2867. goto loser;
  2868. }
  2869. rvstr = (sftkdbCall_DeleteSecmodDB(appName, filename, secmod,
  2870. (char *)args, rw) == SECSuccess)
  2871. ? &success
  2872. : NULL;
  2873. break;
  2874. case SECMOD_MODULE_DB_FUNCTION_RELEASE:
  2875. rvstr = (sftkdbCall_ReleaseSecmodDBData(appName, filename, secmod,
  2876. (char **)args, rw) == SECSuccess)
  2877. ? &success
  2878. : NULL;
  2879. break;
  2880. }
  2881. loser:
  2882. if (secmod)
  2883. PR_smprintf_free(secmod);
  2884. if (appName)
  2885. PORT_Free(appName);
  2886. if (filename)
  2887. PORT_Free(filename);
  2888. #endif /* NSS_DISABLE_DBM */
  2889. return rvstr;
  2890. }
  2891. static void
  2892. nscFreeAllSlots(int moduleIndex)
  2893. {
  2894. /* free all the slots */
  2895. SFTKSlot *slot = NULL;
  2896. CK_SLOT_ID slotID;
  2897. int i;
  2898. if (nscSlotList[moduleIndex]) {
  2899. CK_ULONG tmpSlotCount = nscSlotCount[moduleIndex];
  2900. CK_SLOT_ID_PTR tmpSlotList = nscSlotList[moduleIndex];
  2901. PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
  2902. /* first close all the session */
  2903. for (i = 0; i < (int)tmpSlotCount; i++) {
  2904. slotID = tmpSlotList[i];
  2905. (void)NSC_CloseAllSessions(slotID);
  2906. }
  2907. /* now clear out the statics */
  2908. nscSlotList[moduleIndex] = NULL;
  2909. nscSlotCount[moduleIndex] = 0;
  2910. nscSlotHashTable[moduleIndex] = NULL;
  2911. nscSlotListSize[moduleIndex] = 0;
  2912. for (i = 0; i < (int)tmpSlotCount; i++) {
  2913. slotID = tmpSlotList[i];
  2914. slot = (SFTKSlot *)
  2915. PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
  2916. PORT_Assert(slot);
  2917. if (!slot)
  2918. continue;
  2919. SFTK_DestroySlotData(slot);
  2920. PL_HashTableRemove(tmpSlotHashTable, (void *)slotID);
  2921. }
  2922. PORT_Free(tmpSlotList);
  2923. PL_HashTableDestroy(tmpSlotHashTable);
  2924. }
  2925. }
  2926. static void
  2927. sftk_closePeer(PRBool isFIPS)
  2928. {
  2929. CK_SLOT_ID slotID = isFIPS ? PRIVATE_KEY_SLOT_ID : FIPS_SLOT_ID;
  2930. SFTKSlot *slot;
  2931. int moduleIndex = isFIPS ? NSC_NON_FIPS_MODULE : NSC_FIPS_MODULE;
  2932. PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
  2933. slot = (SFTKSlot *)PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
  2934. if (slot == NULL) {
  2935. return;
  2936. }
  2937. sftk_DBShutdown(slot);
  2938. return;
  2939. }
  2940. extern void sftk_PBELockInit(void);
  2941. extern void sftk_PBELockShutdown(void);
  2942. /* NSC_Initialize initializes the Cryptoki library. */
  2943. CK_RV
  2944. nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
  2945. {
  2946. CK_RV crv = CKR_OK;
  2947. SECStatus rv;
  2948. CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *)pReserved;
  2949. int i;
  2950. int moduleIndex = isFIPS ? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE;
  2951. if (isFIPS) {
  2952. loginWaitTime = PR_SecondsToInterval(1);
  2953. }
  2954. ENABLE_FORK_CHECK();
  2955. sftk_PBELockInit();
  2956. rv = SECOID_Init();
  2957. if (rv != SECSuccess) {
  2958. crv = CKR_DEVICE_ERROR;
  2959. return crv;
  2960. }
  2961. rv = RNG_RNGInit(); /* initialize random number generator */
  2962. if (rv != SECSuccess) {
  2963. crv = CKR_DEVICE_ERROR;
  2964. return crv;
  2965. }
  2966. rv = BL_Init(); /* initialize freebl engine */
  2967. if (rv != SECSuccess) {
  2968. crv = CKR_DEVICE_ERROR;
  2969. return crv;
  2970. }
  2971. /* NOTE:
  2972. * we should be getting out mutexes from this list, not statically binding
  2973. * them from NSPR. This should happen before we allow the internal to split
  2974. * off from the rest on NSS.
  2975. */
  2976. /* initialize the key and cert db's */
  2977. if (init_args && (!(init_args->flags & CKF_OS_LOCKING_OK))) {
  2978. if (init_args->CreateMutex && init_args->DestroyMutex &&
  2979. init_args->LockMutex && init_args->UnlockMutex) {
  2980. /* softoken always uses NSPR (ie. OS locking), and doesn't know how
  2981. * to use the lock functions provided by the application.
  2982. */
  2983. crv = CKR_CANT_LOCK;
  2984. return crv;
  2985. }
  2986. if (init_args->CreateMutex || init_args->DestroyMutex ||
  2987. init_args->LockMutex || init_args->UnlockMutex) {
  2988. /* only some of the lock functions were provided by the
  2989. * application. This is invalid per PKCS#11 spec.
  2990. */
  2991. crv = CKR_ARGUMENTS_BAD;
  2992. return crv;
  2993. }
  2994. }
  2995. crv = CKR_ARGUMENTS_BAD;
  2996. if ((init_args && init_args->LibraryParameters)) {
  2997. sftk_parameters paramStrings;
  2998. crv = sftk_parseParameters((char *)init_args->LibraryParameters, &paramStrings, isFIPS);
  2999. if (crv != CKR_OK) {
  3000. return crv;
  3001. }
  3002. crv = sftk_configure(paramStrings.man, paramStrings.libdes);
  3003. if (crv != CKR_OK) {
  3004. goto loser;
  3005. }
  3006. /* if we have a peer already open, have him close his DB's so we
  3007. * don't clobber each other. */
  3008. if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) {
  3009. sftk_closePeer(isFIPS);
  3010. if (sftk_audit_enabled) {
  3011. if (isFIPS && nsc_init) {
  3012. sftk_LogAuditMessage(NSS_AUDIT_INFO, NSS_AUDIT_FIPS_STATE,
  3013. "enabled FIPS mode");
  3014. } else {
  3015. sftk_LogAuditMessage(NSS_AUDIT_INFO, NSS_AUDIT_FIPS_STATE,
  3016. "disabled FIPS mode");
  3017. }
  3018. }
  3019. }
  3020. for (i = 0; i < paramStrings.token_count; i++) {
  3021. crv = SFTK_SlotInit(paramStrings.configdir,
  3022. paramStrings.updatedir, paramStrings.updateID,
  3023. &paramStrings.tokens[i], moduleIndex);
  3024. if (crv != CKR_OK) {
  3025. nscFreeAllSlots(moduleIndex);
  3026. break;
  3027. }
  3028. }
  3029. loser:
  3030. sftk_freeParams(&paramStrings);
  3031. }
  3032. if (CKR_OK == crv) {
  3033. sftk_InitFreeLists();
  3034. }
  3035. #ifndef NO_FORK_CHECK
  3036. if (CKR_OK == crv) {
  3037. #if defined(CHECK_FORK_MIXED)
  3038. /* Before Solaris 10, fork handlers are not unregistered at dlclose()
  3039. * time. So, we only use pthread_atfork on Solaris 10 and later. For
  3040. * earlier versions, we use PID checks.
  3041. */
  3042. char buf[200];
  3043. int major = 0, minor = 0;
  3044. long rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
  3045. if (rv > 0 && rv < sizeof(buf)) {
  3046. if (2 == sscanf(buf, "%d.%d", &major, &minor)) {
  3047. /* Are we on Solaris 10 or greater ? */
  3048. if (major > 5 || (5 == major && minor >= 10)) {
  3049. /* we are safe to use pthread_atfork */
  3050. usePthread_atfork = PR_TRUE;
  3051. }
  3052. }
  3053. }
  3054. if (usePthread_atfork) {
  3055. pthread_atfork(NULL, NULL, ForkedChild);
  3056. } else {
  3057. myPid = getpid();
  3058. }
  3059. #elif defined(CHECK_FORK_PTHREAD)
  3060. pthread_atfork(NULL, NULL, ForkedChild);
  3061. #elif defined(CHECK_FORK_GETPID)
  3062. myPid = getpid();
  3063. #else
  3064. #error Incorrect fork check method.
  3065. #endif
  3066. }
  3067. #endif
  3068. return crv;
  3069. }
  3070. CK_RV
  3071. NSC_Initialize(CK_VOID_PTR pReserved)
  3072. {
  3073. CK_RV crv;
  3074. sftk_ForkReset(pReserved, &crv);
  3075. if (nsc_init) {
  3076. return CKR_CRYPTOKI_ALREADY_INITIALIZED;
  3077. }
  3078. crv = nsc_CommonInitialize(pReserved, PR_FALSE);
  3079. nsc_init = (PRBool)(crv == CKR_OK);
  3080. return crv;
  3081. }
  3082. /* NSC_Finalize indicates that an application is done with the
  3083. * Cryptoki library.*/
  3084. CK_RV
  3085. nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS)
  3086. {
  3087. /* propagate the fork status to freebl and util */
  3088. BL_SetForkState(parentForkedAfterC_Initialize);
  3089. UTIL_SetForkState(parentForkedAfterC_Initialize);
  3090. nscFreeAllSlots(isFIPS ? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE);
  3091. /* don't muck with the globals if our peer is still initialized */
  3092. if (isFIPS && nsc_init) {
  3093. return CKR_OK;
  3094. }
  3095. if (!isFIPS && nsf_init) {
  3096. return CKR_OK;
  3097. }
  3098. sftk_CleanupFreeLists();
  3099. sftkdb_Shutdown();
  3100. /* This function does not discard all our previously aquired entropy. */
  3101. RNG_RNGShutdown();
  3102. /* tell freeBL to clean up after itself */
  3103. BL_Cleanup();
  3104. /* reset fork status in freebl. We must do this before BL_Unload so that
  3105. * this call doesn't force freebl to be reloaded. */
  3106. BL_SetForkState(PR_FALSE);
  3107. #ifndef NSS_STATIC_SOFTOKEN
  3108. /* unload freeBL shared library from memory. This may only decrement the
  3109. * OS refcount if it's been loaded multiple times, eg. by libssl */
  3110. BL_Unload();
  3111. #endif
  3112. /* clean up the default OID table */
  3113. SECOID_Shutdown();
  3114. sftk_PBELockShutdown();
  3115. /* reset fork status in util */
  3116. UTIL_SetForkState(PR_FALSE);
  3117. nsc_init = PR_FALSE;
  3118. #ifndef NO_FORK_CHECK
  3119. #ifdef CHECK_FORK_MIXED
  3120. if (!usePthread_atfork) {
  3121. myPid = 0; /* allow CHECK_FORK in the next softoken initialization to
  3122. * succeed */
  3123. } else {
  3124. forked = PR_FALSE; /* allow reinitialization */
  3125. }
  3126. #elif defined(CHECK_FORK_GETPID)
  3127. myPid = 0; /* allow reinitialization */
  3128. #elif defined(CHECK_FORK_PTHREAD)
  3129. forked = PR_FALSE; /* allow reinitialization */
  3130. #endif
  3131. #endif
  3132. return CKR_OK;
  3133. }
  3134. /* Hard-reset the entire softoken PKCS#11 module if the parent process forked
  3135. * while it was initialized. */
  3136. PRBool
  3137. sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV *crv)
  3138. {
  3139. #ifndef NO_FORK_CHECK
  3140. if (PARENT_FORKED()) {
  3141. parentForkedAfterC_Initialize = PR_TRUE;
  3142. if (nsc_init) {
  3143. /* finalize non-FIPS token */
  3144. *crv = nsc_CommonFinalize(pReserved, PR_FALSE);
  3145. PORT_Assert(CKR_OK == *crv);
  3146. nsc_init = (PRBool) !(*crv == CKR_OK);
  3147. }
  3148. if (nsf_init) {
  3149. /* finalize FIPS token */
  3150. *crv = nsc_CommonFinalize(pReserved, PR_TRUE);
  3151. PORT_Assert(CKR_OK == *crv);
  3152. nsf_init = (PRBool) !(*crv == CKR_OK);
  3153. }
  3154. parentForkedAfterC_Initialize = PR_FALSE;
  3155. return PR_TRUE;
  3156. }
  3157. #endif
  3158. return PR_FALSE;
  3159. }
  3160. /* NSC_Finalize indicates that an application is done with the
  3161. * Cryptoki library.*/
  3162. CK_RV
  3163. NSC_Finalize(CK_VOID_PTR pReserved)
  3164. {
  3165. CK_RV crv;
  3166. /* reset entire PKCS#11 module upon fork */
  3167. if (sftk_ForkReset(pReserved, &crv)) {
  3168. return crv;
  3169. }
  3170. if (!nsc_init) {
  3171. return CKR_OK;
  3172. }
  3173. crv = nsc_CommonFinalize(pReserved, PR_FALSE);
  3174. nsc_init = (PRBool) !(crv == CKR_OK);
  3175. return crv;
  3176. }
  3177. extern const char __nss_softokn_version[];
  3178. /* NSC_GetInfo returns general information about Cryptoki. */
  3179. CK_RV
  3180. NSC_GetInfo(CK_INFO_PTR pInfo)
  3181. {
  3182. #define NSS_VERSION_VARIABLE __nss_softokn_version
  3183. #include "verref.h"
  3184. CHECK_FORK();
  3185. pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
  3186. pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
  3187. PORT_Memcpy(pInfo->manufacturerID, manufacturerID, 32);
  3188. pInfo->libraryVersion.major = SOFTOKEN_VMAJOR;
  3189. pInfo->libraryVersion.minor = SOFTOKEN_VMINOR;
  3190. PORT_Memcpy(pInfo->libraryDescription, libraryDescription, 32);
  3191. pInfo->flags = 0;
  3192. return CKR_OK;
  3193. }
  3194. /* NSC_GetInfo returns general information about Cryptoki. */
  3195. CK_RV
  3196. NSC_GetInfoV2(CK_INFO_PTR pInfo)
  3197. {
  3198. CHECK_FORK();
  3199. pInfo->cryptokiVersion.major = 2;
  3200. pInfo->cryptokiVersion.minor = 40;
  3201. PORT_Memcpy(pInfo->manufacturerID, manufacturerID, 32);
  3202. pInfo->libraryVersion.major = SOFTOKEN_VMAJOR;
  3203. pInfo->libraryVersion.minor = SOFTOKEN_VMINOR;
  3204. PORT_Memcpy(pInfo->libraryDescription, libraryDescription, 32);
  3205. pInfo->flags = 0;
  3206. return CKR_OK;
  3207. }
  3208. /* NSC_GetSlotList obtains a list of slots in the system. */
  3209. CK_RV
  3210. nsc_CommonGetSlotList(CK_BBOOL tokenPresent,
  3211. CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex)
  3212. {
  3213. *pulCount = nscSlotCount[moduleIndex];
  3214. if (pSlotList != NULL) {
  3215. PORT_Memcpy(pSlotList, nscSlotList[moduleIndex],
  3216. nscSlotCount[moduleIndex] * sizeof(CK_SLOT_ID));
  3217. }
  3218. return CKR_OK;
  3219. }
  3220. /* NSC_GetSlotList obtains a list of slots in the system. */
  3221. CK_RV
  3222. NSC_GetSlotList(CK_BBOOL tokenPresent,
  3223. CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
  3224. {
  3225. CHECK_FORK();
  3226. return nsc_CommonGetSlotList(tokenPresent, pSlotList, pulCount,
  3227. NSC_NON_FIPS_MODULE);
  3228. }
  3229. /* NSC_GetSlotInfo obtains information about a particular slot in the system. */
  3230. CK_RV
  3231. NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
  3232. {
  3233. SFTKSlot *slot = sftk_SlotFromID(slotID, PR_TRUE);
  3234. CHECK_FORK();
  3235. if (slot == NULL)
  3236. return CKR_SLOT_ID_INVALID;
  3237. PORT_Memcpy(pInfo->manufacturerID, manufacturerID,
  3238. sizeof(pInfo->manufacturerID));
  3239. PORT_Memcpy(pInfo->slotDescription, slot->slotDescription,
  3240. sizeof(pInfo->slotDescription));
  3241. pInfo->flags = (slot->present) ? CKF_TOKEN_PRESENT : 0;
  3242. /* all user defined slots are defined as removable */
  3243. if (slotID >= SFTK_MIN_USER_SLOT_ID) {
  3244. pInfo->flags |= CKF_REMOVABLE_DEVICE;
  3245. } else {
  3246. /* In the case where we are doing a merge update, we need
  3247. * the DB slot to be removable so the token name can change
  3248. * appropriately. */
  3249. SFTKDBHandle *handle = sftk_getKeyDB(slot);
  3250. if (handle) {
  3251. if (sftkdb_InUpdateMerge(handle)) {
  3252. pInfo->flags |= CKF_REMOVABLE_DEVICE;
  3253. }
  3254. sftk_freeDB(handle);
  3255. }
  3256. }
  3257. /* If there is no key database, this is for example the case when NSS was
  3258. * initialized with NSS_NoDbInit(), then there won't be any point in
  3259. * requesting a PIN. Set the CKF_USER_PIN_INITIALIZED bit so that
  3260. * PK11_NeedUserInit() doesn't indicate that a PIN is needed.
  3261. */
  3262. if (slot->keyDB == NULL) {
  3263. pInfo->flags |= CKF_USER_PIN_INITIALIZED;
  3264. }
  3265. /* ok we really should read it out of the keydb file. */
  3266. /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
  3267. pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR;
  3268. pInfo->hardwareVersion.minor = SOFTOKEN_VMINOR;
  3269. pInfo->firmwareVersion.major = SOFTOKEN_VPATCH;
  3270. pInfo->firmwareVersion.minor = SOFTOKEN_VBUILD;
  3271. return CKR_OK;
  3272. }
  3273. /*
  3274. * check the current state of the 'needLogin' flag in case the database has
  3275. * been changed underneath us.
  3276. */
  3277. static PRBool
  3278. sftk_checkNeedLogin(SFTKSlot *slot, SFTKDBHandle *keyHandle)
  3279. {
  3280. if (sftkdb_PWCached(keyHandle) == SECSuccess) {
  3281. return slot->needLogin;
  3282. }
  3283. slot->needLogin = (PRBool)!sftk_hasNullPassword(slot, keyHandle);
  3284. return (slot->needLogin);
  3285. }
  3286. static PRBool
  3287. sftk_isBlank(const char *s, int len)
  3288. {
  3289. int i;
  3290. for (i = 0; i < len; i++) {
  3291. if (s[i] != ' ') {
  3292. return PR_FALSE;
  3293. }
  3294. }
  3295. return PR_TRUE;
  3296. }
  3297. /* NSC_GetTokenInfo obtains information about a particular token in
  3298. * the system. */
  3299. CK_RV
  3300. NSC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
  3301. {
  3302. SFTKSlot *slot;
  3303. SFTKDBHandle *handle;
  3304. CHECK_FORK();
  3305. if (!nsc_init && !nsf_init)
  3306. return CKR_CRYPTOKI_NOT_INITIALIZED;
  3307. slot = sftk_SlotFromID(slotID, PR_FALSE);
  3308. if (slot == NULL)
  3309. return CKR_SLOT_ID_INVALID;
  3310. PORT_Memcpy(pInfo->manufacturerID, manufacturerID, 32);
  3311. PORT_Memcpy(pInfo->model, "NSS 3 ", 16);
  3312. PORT_Memcpy(pInfo->serialNumber, "0000000000000000", 16);
  3313. PORT_Memcpy(pInfo->utcTime, "0000000000000000", 16);
  3314. pInfo->ulMaxSessionCount = 0; /* arbitrarily large */
  3315. pInfo->ulMaxRwSessionCount = 0; /* arbitrarily large */
  3316. PZ_Lock(slot->slotLock); /* Protect sessionCount / rwSessioncount */
  3317. pInfo->ulSessionCount = slot->sessionCount;
  3318. pInfo->ulRwSessionCount = slot->rwSessionCount;
  3319. PZ_Unlock(slot->slotLock); /* Unlock before sftk_getKeyDB */
  3320. pInfo->firmwareVersion.major = 0;
  3321. pInfo->firmwareVersion.minor = 0;
  3322. PORT_Memcpy(pInfo->label, slot->tokDescription, sizeof(pInfo->label));
  3323. handle = sftk_getKeyDB(slot);
  3324. pInfo->flags = CKF_RNG | CKF_DUAL_CRYPTO_OPERATIONS;
  3325. if (handle == NULL) {
  3326. pInfo->flags |= CKF_WRITE_PROTECTED;
  3327. pInfo->ulMaxPinLen = 0;
  3328. pInfo->ulMinPinLen = 0;
  3329. pInfo->ulTotalPublicMemory = 0;
  3330. pInfo->ulFreePublicMemory = 0;
  3331. pInfo->ulTotalPrivateMemory = 0;
  3332. pInfo->ulFreePrivateMemory = 0;
  3333. pInfo->hardwareVersion.major = 4;
  3334. pInfo->hardwareVersion.minor = 0;
  3335. } else {
  3336. /*
  3337. * we have three possible states which we may be in:
  3338. * (1) No DB password has been initialized. This also means we
  3339. * have no keys in the key db.
  3340. * (2) Password initialized to NULL. This means we have keys, but
  3341. * the user has chosen not use a password.
  3342. * (3) Finally we have an initialized password whicn is not NULL, and
  3343. * we will need to prompt for it.
  3344. */
  3345. if (sftkdb_HasPasswordSet(handle) == SECFailure) {
  3346. pInfo->flags |= CKF_LOGIN_REQUIRED;
  3347. } else if (!sftk_checkNeedLogin(slot, handle)) {
  3348. pInfo->flags |= CKF_USER_PIN_INITIALIZED;
  3349. } else {
  3350. pInfo->flags |= CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
  3351. /*
  3352. * if we are doing a merge style update, and we need to get the password
  3353. * of our source database (the database we are updating from), make sure we
  3354. * return a token name that will match the database we are prompting for.
  3355. */
  3356. if (sftkdb_NeedUpdateDBPassword(handle)) {
  3357. /* if we have an update tok description, use it. otherwise
  3358. * use the updateID for this database */
  3359. if (!sftk_isBlank(slot->updateTokDescription,
  3360. sizeof(pInfo->label))) {
  3361. PORT_Memcpy(pInfo->label, slot->updateTokDescription,
  3362. sizeof(pInfo->label));
  3363. } else {
  3364. /* build from updateID */
  3365. const char *updateID = sftkdb_GetUpdateID(handle);
  3366. if (updateID) {
  3367. sftk_setStringName(updateID, (char *)pInfo->label,
  3368. sizeof(pInfo->label), PR_FALSE);
  3369. }
  3370. }
  3371. }
  3372. }
  3373. pInfo->ulMaxPinLen = SFTK_MAX_PIN;
  3374. pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
  3375. pInfo->ulTotalPublicMemory = 1;
  3376. pInfo->ulFreePublicMemory = 1;
  3377. pInfo->ulTotalPrivateMemory = 1;
  3378. pInfo->ulFreePrivateMemory = 1;
  3379. #ifdef SHDB_FIXME
  3380. pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION;
  3381. pInfo->hardwareVersion.minor = handle->version;
  3382. #else
  3383. pInfo->hardwareVersion.major = 0;
  3384. pInfo->hardwareVersion.minor = 0;
  3385. #endif
  3386. sftk_freeDB(handle);
  3387. }
  3388. /*
  3389. * CKF_LOGIN_REQUIRED CKF_USER_PIN_INITIALIZED how CKF_TOKEN_INITIALIZED
  3390. * should be set
  3391. * 0 0 1
  3392. * 1 0 0
  3393. * 0 1 1
  3394. * 1 1 1
  3395. */
  3396. if (!(pInfo->flags & CKF_LOGIN_REQUIRED) ||
  3397. (pInfo->flags & CKF_USER_PIN_INITIALIZED)) {
  3398. pInfo->flags |= CKF_TOKEN_INITIALIZED;
  3399. }
  3400. return CKR_OK;
  3401. }
  3402. /* NSC_GetMechanismList obtains a list of mechanism types
  3403. * supported by a token. */
  3404. CK_RV
  3405. NSC_GetMechanismList(CK_SLOT_ID slotID,
  3406. CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount)
  3407. {
  3408. CK_ULONG i;
  3409. CHECK_FORK();
  3410. switch (slotID) {
  3411. /* default: */
  3412. case NETSCAPE_SLOT_ID:
  3413. *pulCount = mechanismCount;
  3414. if (pMechanismList != NULL) {
  3415. for (i = 0; i < mechanismCount; i++) {
  3416. pMechanismList[i] = mechanisms[i].type;
  3417. }
  3418. }
  3419. break;
  3420. default:
  3421. *pulCount = 0;
  3422. for (i = 0; i < mechanismCount; i++) {
  3423. if (mechanisms[i].privkey) {
  3424. (*pulCount)++;
  3425. if (pMechanismList != NULL) {
  3426. *pMechanismList++ = mechanisms[i].type;
  3427. }
  3428. }
  3429. }
  3430. break;
  3431. }
  3432. return CKR_OK;
  3433. }
  3434. /* NSC_GetMechanismInfo obtains information about a particular mechanism
  3435. * possibly supported by a token. */
  3436. CK_RV
  3437. NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
  3438. CK_MECHANISM_INFO_PTR pInfo)
  3439. {
  3440. PRBool isPrivateKey;
  3441. CK_ULONG i;
  3442. CHECK_FORK();
  3443. switch (slotID) {
  3444. case NETSCAPE_SLOT_ID:
  3445. isPrivateKey = PR_FALSE;
  3446. break;
  3447. default:
  3448. isPrivateKey = PR_TRUE;
  3449. break;
  3450. }
  3451. for (i = 0; i < mechanismCount; i++) {
  3452. if (type == mechanisms[i].type) {
  3453. if (isPrivateKey && !mechanisms[i].privkey) {
  3454. return CKR_MECHANISM_INVALID;
  3455. }
  3456. PORT_Memcpy(pInfo, &mechanisms[i].info, sizeof(CK_MECHANISM_INFO));
  3457. return CKR_OK;
  3458. }
  3459. }
  3460. return CKR_MECHANISM_INVALID;
  3461. }
  3462. /*
  3463. * If we are using the V2 interface, strip out the message flags
  3464. */
  3465. #define SFTK_MESSAGE_FLAGS (CKF_MESSAGE_ENCRYPT | CKF_MESSAGE_DECRYPT | CKF_MESSAGE_SIGN | CKF_MESSAGE_VERIFY)
  3466. CK_RV
  3467. NSC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
  3468. CK_MECHANISM_INFO_PTR pInfo)
  3469. {
  3470. CK_RV crv;
  3471. crv = NSC_GetMechanismInfo(slotID, type, pInfo);
  3472. if (crv == CKR_OK) {
  3473. pInfo->flags = pInfo->flags & ~SFTK_MESSAGE_FLAGS;
  3474. }
  3475. return crv;
  3476. }
  3477. CK_RV
  3478. sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op)
  3479. {
  3480. CK_ULONG i;
  3481. CK_FLAGS flags;
  3482. switch (op) {
  3483. case CKA_ENCRYPT:
  3484. flags = CKF_ENCRYPT;
  3485. break;
  3486. case CKA_DECRYPT:
  3487. flags = CKF_DECRYPT;
  3488. break;
  3489. case CKA_WRAP:
  3490. flags = CKF_WRAP;
  3491. break;
  3492. case CKA_UNWRAP:
  3493. flags = CKF_UNWRAP;
  3494. break;
  3495. case CKA_SIGN:
  3496. flags = CKF_SIGN;
  3497. break;
  3498. case CKA_SIGN_RECOVER:
  3499. flags = CKF_SIGN_RECOVER;
  3500. break;
  3501. case CKA_VERIFY:
  3502. flags = CKF_VERIFY;
  3503. break;
  3504. case CKA_VERIFY_RECOVER:
  3505. flags = CKF_VERIFY_RECOVER;
  3506. break;
  3507. case CKA_DERIVE:
  3508. flags = CKF_DERIVE;
  3509. break;
  3510. case CKA_NSS_MESSAGE | CKA_ENCRYPT:
  3511. flags = CKF_MESSAGE_ENCRYPT;
  3512. break;
  3513. case CKA_NSS_MESSAGE | CKA_DECRYPT:
  3514. flags = CKF_MESSAGE_DECRYPT;
  3515. break;
  3516. case CKA_NSS_MESSAGE | CKA_SIGN:
  3517. flags = CKF_MESSAGE_SIGN;
  3518. break;
  3519. case CKA_NSS_MESSAGE | CKA_VERIFY:
  3520. flags = CKF_MESSAGE_VERIFY;
  3521. break;
  3522. default:
  3523. return CKR_ARGUMENTS_BAD;
  3524. }
  3525. for (i = 0; i < mechanismCount; i++) {
  3526. if (type == mechanisms[i].type) {
  3527. return (flags & mechanisms[i].info.flags) ? CKR_OK
  3528. : CKR_MECHANISM_INVALID;
  3529. }
  3530. }
  3531. return CKR_MECHANISM_INVALID;
  3532. }
  3533. /* NSC_InitToken initializes a token. */
  3534. CK_RV
  3535. NSC_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin,
  3536. CK_ULONG ulPinLen, CK_CHAR_PTR pLabel)
  3537. {
  3538. SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
  3539. SFTKDBHandle *handle;
  3540. SECStatus rv;
  3541. unsigned int i;
  3542. SFTKObject *object;
  3543. CHECK_FORK();
  3544. if (slot == NULL)
  3545. return CKR_SLOT_ID_INVALID;
  3546. /* don't initialize the database if we aren't talking to a token
  3547. * that uses the key database.
  3548. */
  3549. if (slotID == NETSCAPE_SLOT_ID) {
  3550. return CKR_TOKEN_WRITE_PROTECTED;
  3551. }
  3552. /* first, delete all our loaded key and cert objects from our
  3553. * internal list. */
  3554. PZ_Lock(slot->objectLock);
  3555. for (i = 0; i < slot->sessObjHashSize; i++) {
  3556. do {
  3557. object = slot->sessObjHashTable[i];
  3558. /* hand deque */
  3559. /* this duplicates function of NSC_close session functions, but
  3560. * because we know that we are freeing all the sessions, we can
  3561. * do more efficient processing */
  3562. if (object) {
  3563. slot->sessObjHashTable[i] = object->next;
  3564. if (object->next)
  3565. object->next->prev = NULL;
  3566. object->next = object->prev = NULL;
  3567. }
  3568. if (object)
  3569. sftk_FreeObject(object);
  3570. } while (object != NULL);
  3571. }
  3572. slot->DB_loaded = PR_FALSE;
  3573. PZ_Unlock(slot->objectLock);
  3574. /* then clear out the key database */
  3575. handle = sftk_getKeyDB(slot);
  3576. if (handle == NULL) {
  3577. return CKR_TOKEN_WRITE_PROTECTED;
  3578. }
  3579. rv = sftkdb_ResetKeyDB(handle);
  3580. /* clear the password */
  3581. sftkdb_ClearPassword(handle);
  3582. /* update slot->needLogin (should be true now since no password is set) */
  3583. sftk_checkNeedLogin(slot, handle);
  3584. sftk_freeDB(handle);
  3585. if (rv != SECSuccess) {
  3586. return CKR_DEVICE_ERROR;
  3587. }
  3588. return CKR_OK;
  3589. }
  3590. /* NSC_InitPIN initializes the normal user's PIN. */
  3591. CK_RV
  3592. NSC_InitPIN(CK_SESSION_HANDLE hSession,
  3593. CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
  3594. {
  3595. SFTKSession *sp = NULL;
  3596. SFTKSlot *slot;
  3597. SFTKDBHandle *handle = NULL;
  3598. char newPinStr[SFTK_MAX_PIN + 1];
  3599. SECStatus rv;
  3600. CK_RV crv = CKR_SESSION_HANDLE_INVALID;
  3601. PRBool tokenRemoved = PR_FALSE;
  3602. CHECK_FORK();
  3603. sp = sftk_SessionFromHandle(hSession);
  3604. if (sp == NULL) {
  3605. goto loser;
  3606. }
  3607. slot = sftk_SlotFromSession(sp);
  3608. if (slot == NULL) {
  3609. goto loser;
  3610. }
  3611. handle = sftk_getKeyDB(slot);
  3612. if (handle == NULL) {
  3613. crv = CKR_PIN_LEN_RANGE;
  3614. goto loser;
  3615. }
  3616. if (sp->info.state != CKS_RW_SO_FUNCTIONS) {
  3617. crv = CKR_USER_NOT_LOGGED_IN;
  3618. goto loser;
  3619. }
  3620. sftk_FreeSession(sp);
  3621. sp = NULL;
  3622. /* make sure the pins aren't too long */
  3623. if (ulPinLen > SFTK_MAX_PIN) {
  3624. crv = CKR_PIN_LEN_RANGE;
  3625. goto loser;
  3626. }
  3627. if (ulPinLen < (CK_ULONG)slot->minimumPinLen) {
  3628. crv = CKR_PIN_LEN_RANGE;
  3629. goto loser;
  3630. }
  3631. if (sftkdb_HasPasswordSet(handle) != SECFailure) {
  3632. crv = CKR_DEVICE_ERROR;
  3633. goto loser;
  3634. }
  3635. /* convert to null terminated string */
  3636. PORT_Memcpy(newPinStr, pPin, ulPinLen);
  3637. newPinStr[ulPinLen] = 0;
  3638. /* build the hashed pins which we pass around */
  3639. /* change the data base */
  3640. rv = sftkdb_ChangePassword(handle, NULL, newPinStr, &tokenRemoved);
  3641. if (tokenRemoved) {
  3642. sftk_CloseAllSessions(slot, PR_FALSE);
  3643. }
  3644. sftk_freeDB(handle);
  3645. handle = NULL;
  3646. /* Now update our local copy of the pin */
  3647. if (rv == SECSuccess) {
  3648. if (ulPinLen == 0)
  3649. slot->needLogin = PR_FALSE;
  3650. /* database has been initialized, now force min password in FIPS
  3651. * mode. NOTE: if we are in level1, we may not have a password, but
  3652. * forcing it now will prevent an insufficient password from being set.
  3653. */
  3654. if ((sftk_GetModuleIndex(slot->slotID) == NSC_FIPS_MODULE) &&
  3655. (slot->minimumPinLen < FIPS_MIN_PIN)) {
  3656. slot->minimumPinLen = FIPS_MIN_PIN;
  3657. }
  3658. return CKR_OK;
  3659. }
  3660. crv = CKR_PIN_INCORRECT;
  3661. loser:
  3662. if (sp) {
  3663. sftk_FreeSession(sp);
  3664. }
  3665. if (handle) {
  3666. sftk_freeDB(handle);
  3667. }
  3668. return crv;
  3669. }
  3670. /* NSC_SetPIN modifies the PIN of user that is currently logged in. */
  3671. /* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
  3672. CK_RV
  3673. NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
  3674. CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
  3675. {
  3676. SFTKSession *sp = NULL;
  3677. SFTKSlot *slot;
  3678. SFTKDBHandle *handle = NULL;
  3679. char newPinStr[SFTK_MAX_PIN + 1], oldPinStr[SFTK_MAX_PIN + 1];
  3680. SECStatus rv;
  3681. CK_RV crv = CKR_SESSION_HANDLE_INVALID;
  3682. PRBool tokenRemoved = PR_FALSE;
  3683. CHECK_FORK();
  3684. sp = sftk_SessionFromHandle(hSession);
  3685. if (sp == NULL) {
  3686. goto loser;
  3687. }
  3688. slot = sftk_SlotFromSession(sp);
  3689. if (!slot) {
  3690. goto loser;
  3691. }
  3692. handle = sftk_getKeyDB(slot);
  3693. if (handle == NULL) {
  3694. sftk_FreeSession(sp);
  3695. return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */
  3696. }
  3697. if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
  3698. crv = CKR_USER_NOT_LOGGED_IN;
  3699. goto loser;
  3700. }
  3701. sftk_FreeSession(sp);
  3702. sp = NULL;
  3703. /* make sure the pins aren't too long */
  3704. if ((ulNewLen > SFTK_MAX_PIN) || (ulOldLen > SFTK_MAX_PIN)) {
  3705. crv = CKR_PIN_LEN_RANGE;
  3706. goto loser;
  3707. }
  3708. /* check the length of new pin, unless both old and new passwords
  3709. * are empty */
  3710. if ((ulNewLen != 0 || ulOldLen != 0) &&
  3711. ulNewLen < (CK_ULONG)slot->minimumPinLen) {
  3712. crv = CKR_PIN_LEN_RANGE;
  3713. goto loser;
  3714. }
  3715. /* convert to null terminated string */
  3716. PORT_Memcpy(newPinStr, pNewPin, ulNewLen);
  3717. newPinStr[ulNewLen] = 0;
  3718. PORT_Memcpy(oldPinStr, pOldPin, ulOldLen);
  3719. oldPinStr[ulOldLen] = 0;
  3720. /* change the data base password */
  3721. PR_Lock(slot->pwCheckLock);
  3722. rv = sftkdb_ChangePassword(handle, oldPinStr, newPinStr, &tokenRemoved);
  3723. if (tokenRemoved) {
  3724. sftk_CloseAllSessions(slot, PR_FALSE);
  3725. }
  3726. if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
  3727. PR_Sleep(loginWaitTime);
  3728. }
  3729. PR_Unlock(slot->pwCheckLock);
  3730. /* Now update our local copy of the pin */
  3731. if (rv == SECSuccess) {
  3732. PZ_Lock(slot->slotLock);
  3733. slot->needLogin = (PRBool)(ulNewLen != 0);
  3734. slot->isLoggedIn = (PRBool)(sftkdb_PWCached(handle) == SECSuccess);
  3735. PZ_Unlock(slot->slotLock);
  3736. /* Reset login flags. */
  3737. if (ulNewLen == 0) {
  3738. PZ_Lock(slot->slotLock);
  3739. slot->isLoggedIn = PR_FALSE;
  3740. slot->ssoLoggedIn = PR_FALSE;
  3741. PZ_Unlock(slot->slotLock);
  3742. tokenRemoved = PR_FALSE;
  3743. rv = sftkdb_CheckPasswordNull(handle, &tokenRemoved);
  3744. if (tokenRemoved) {
  3745. sftk_CloseAllSessions(slot, PR_FALSE);
  3746. }
  3747. }
  3748. sftk_update_all_states(slot);
  3749. sftk_freeDB(handle);
  3750. return CKR_OK;
  3751. }
  3752. crv = CKR_PIN_INCORRECT;
  3753. loser:
  3754. if (sp) {
  3755. sftk_FreeSession(sp);
  3756. }
  3757. if (handle) {
  3758. sftk_freeDB(handle);
  3759. }
  3760. return crv;
  3761. }
  3762. /* NSC_OpenSession opens a session between an application and a token. */
  3763. CK_RV
  3764. NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
  3765. CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
  3766. {
  3767. SFTKSlot *slot;
  3768. CK_SESSION_HANDLE sessionID;
  3769. SFTKSession *session;
  3770. SFTKSession *sameID;
  3771. CHECK_FORK();
  3772. slot = sftk_SlotFromID(slotID, PR_FALSE);
  3773. if (slot == NULL)
  3774. return CKR_SLOT_ID_INVALID;
  3775. /* new session (we only have serial sessions) */
  3776. session = sftk_NewSession(slotID, Notify, pApplication,
  3777. flags | CKF_SERIAL_SESSION);
  3778. if (session == NULL)
  3779. return CKR_HOST_MEMORY;
  3780. if (slot->readOnly && (flags & CKF_RW_SESSION)) {
  3781. /* NETSCAPE_SLOT_ID is Read ONLY */
  3782. session->info.flags &= ~CKF_RW_SESSION;
  3783. }
  3784. PZ_Lock(slot->slotLock);
  3785. ++slot->sessionCount;
  3786. PZ_Unlock(slot->slotLock);
  3787. if (session->info.flags & CKF_RW_SESSION) {
  3788. (void)PR_ATOMIC_INCREMENT(&slot->rwSessionCount);
  3789. }
  3790. do {
  3791. PZLock *lock;
  3792. do {
  3793. sessionID = (PR_ATOMIC_INCREMENT(&slot->sessionIDCount) & 0xffffff) | (slot->index << 24);
  3794. } while (sessionID == CK_INVALID_HANDLE);
  3795. lock = SFTK_SESSION_LOCK(slot, sessionID);
  3796. PZ_Lock(lock);
  3797. sftkqueue_find(sameID, sessionID, slot->head, slot->sessHashSize);
  3798. if (sameID == NULL) {
  3799. session->handle = sessionID;
  3800. sftk_update_state(slot, session);
  3801. sftkqueue_add(session, sessionID, slot->head, slot->sessHashSize);
  3802. } else {
  3803. slot->sessionIDConflict++; /* for debugging */
  3804. }
  3805. PZ_Unlock(lock);
  3806. } while (sameID != NULL);
  3807. *phSession = sessionID;
  3808. return CKR_OK;
  3809. }
  3810. /* NSC_CloseSession closes a session between an application and a token. */
  3811. CK_RV
  3812. NSC_CloseSession(CK_SESSION_HANDLE hSession)
  3813. {
  3814. SFTKSlot *slot;
  3815. SFTKSession *session;
  3816. PRBool sessionFound;
  3817. PZLock *lock;
  3818. CHECK_FORK();
  3819. session = sftk_SessionFromHandle(hSession);
  3820. if (session == NULL)
  3821. return CKR_SESSION_HANDLE_INVALID;
  3822. slot = sftk_SlotFromSession(session);
  3823. sessionFound = PR_FALSE;
  3824. /* lock */
  3825. lock = SFTK_SESSION_LOCK(slot, hSession);
  3826. PZ_Lock(lock);
  3827. if (sftkqueue_is_queued(session, hSession, slot->head, slot->sessHashSize)) {
  3828. sessionFound = PR_TRUE;
  3829. sftkqueue_delete(session, hSession, slot->head, slot->sessHashSize);
  3830. }
  3831. PZ_Unlock(lock);
  3832. if (sessionFound) {
  3833. SFTKDBHandle *handle;
  3834. handle = sftk_getKeyDB(slot);
  3835. PZ_Lock(slot->slotLock);
  3836. if (--slot->sessionCount == 0) {
  3837. slot->isLoggedIn = PR_FALSE;
  3838. if (slot->needLogin && handle) {
  3839. sftkdb_ClearPassword(handle);
  3840. }
  3841. }
  3842. PZ_Unlock(slot->slotLock);
  3843. if (handle) {
  3844. sftk_freeDB(handle);
  3845. }
  3846. if (session->info.flags & CKF_RW_SESSION) {
  3847. (void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
  3848. }
  3849. sftk_DestroySession(session);
  3850. session = NULL;
  3851. }
  3852. return CKR_OK;
  3853. }
  3854. /* NSC_CloseAllSessions closes all sessions with a token. */
  3855. CK_RV
  3856. NSC_CloseAllSessions(CK_SLOT_ID slotID)
  3857. {
  3858. SFTKSlot *slot;
  3859. #ifndef NO_FORK_CHECK
  3860. /* skip fork check if we are being called from C_Initialize or C_Finalize */
  3861. if (!parentForkedAfterC_Initialize) {
  3862. CHECK_FORK();
  3863. }
  3864. #endif
  3865. slot = sftk_SlotFromID(slotID, PR_FALSE);
  3866. if (slot == NULL)
  3867. return CKR_SLOT_ID_INVALID;
  3868. return sftk_CloseAllSessions(slot, PR_TRUE);
  3869. }
  3870. /* NSC_GetSessionInfo obtains information about the session. */
  3871. CK_RV
  3872. NSC_GetSessionInfo(CK_SESSION_HANDLE hSession,
  3873. CK_SESSION_INFO_PTR pInfo)
  3874. {
  3875. SFTKSession *session;
  3876. CHECK_FORK();
  3877. session = sftk_SessionFromHandle(hSession);
  3878. if (session == NULL)
  3879. return CKR_SESSION_HANDLE_INVALID;
  3880. PORT_Memcpy(pInfo, &session->info, sizeof(CK_SESSION_INFO));
  3881. sftk_FreeSession(session);
  3882. return CKR_OK;
  3883. }
  3884. /* NSC_Login logs a user into a token. */
  3885. CK_RV
  3886. NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
  3887. CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
  3888. {
  3889. SFTKSlot *slot;
  3890. SFTKSession *session;
  3891. SFTKDBHandle *handle;
  3892. CK_FLAGS sessionFlags;
  3893. SECStatus rv;
  3894. CK_RV crv;
  3895. char pinStr[SFTK_MAX_PIN + 1];
  3896. PRBool tokenRemoved = PR_FALSE;
  3897. CHECK_FORK();
  3898. /* get the slot */
  3899. slot = sftk_SlotFromSessionHandle(hSession);
  3900. if (slot == NULL) {
  3901. return CKR_SESSION_HANDLE_INVALID;
  3902. }
  3903. /* make sure the session is valid */
  3904. session = sftk_SessionFromHandle(hSession);
  3905. if (session == NULL) {
  3906. return CKR_SESSION_HANDLE_INVALID;
  3907. }
  3908. sessionFlags = session->info.flags;
  3909. sftk_FreeSession(session);
  3910. session = NULL;
  3911. /* can't log into the Netscape Slot */
  3912. if (slot->slotID == NETSCAPE_SLOT_ID) {
  3913. return CKR_USER_TYPE_INVALID;
  3914. }
  3915. if (slot->isLoggedIn)
  3916. return CKR_USER_ALREADY_LOGGED_IN;
  3917. if (!slot->needLogin) {
  3918. return ulPinLen ? CKR_PIN_INCORRECT : CKR_OK;
  3919. }
  3920. slot->ssoLoggedIn = PR_FALSE;
  3921. if (ulPinLen > SFTK_MAX_PIN)
  3922. return CKR_PIN_LEN_RANGE;
  3923. /* convert to null terminated string */
  3924. if (ulPinLen) {
  3925. PORT_Memcpy(pinStr, pPin, ulPinLen);
  3926. }
  3927. pinStr[ulPinLen] = 0;
  3928. handle = sftk_getKeyDB(slot);
  3929. if (handle == NULL) {
  3930. return CKR_USER_TYPE_INVALID;
  3931. }
  3932. /*
  3933. * Deal with bootstrap. We allow the SSO to login in with a NULL
  3934. * password if and only if we haven't initialized the KEY DB yet.
  3935. * We only allow this on a RW session.
  3936. */
  3937. rv = sftkdb_HasPasswordSet(handle);
  3938. if (rv == SECFailure) {
  3939. /* allow SSO's to log in only if there is not password on the
  3940. * key database */
  3941. if (((userType == CKU_SO) && (sessionFlags & CKF_RW_SESSION))
  3942. /* fips always needs to authenticate, even if there isn't a db */
  3943. || (slot->slotID == FIPS_SLOT_ID)) {
  3944. /* should this be a fixed password? */
  3945. if (ulPinLen == 0) {
  3946. sftkdb_ClearPassword(handle);
  3947. PZ_Lock(slot->slotLock);
  3948. slot->isLoggedIn = PR_TRUE;
  3949. slot->ssoLoggedIn = (PRBool)(userType == CKU_SO);
  3950. PZ_Unlock(slot->slotLock);
  3951. sftk_update_all_states(slot);
  3952. crv = CKR_OK;
  3953. goto done;
  3954. }
  3955. crv = CKR_PIN_INCORRECT;
  3956. goto done;
  3957. }
  3958. crv = CKR_USER_TYPE_INVALID;
  3959. goto done;
  3960. }
  3961. /* don't allow the SSO to log in if the user is already initialized */
  3962. if (userType != CKU_USER) {
  3963. crv = CKR_USER_TYPE_INVALID;
  3964. goto done;
  3965. }
  3966. /* build the hashed pins which we pass around */
  3967. PR_Lock(slot->pwCheckLock);
  3968. rv = sftkdb_CheckPassword(handle, pinStr, &tokenRemoved);
  3969. if (tokenRemoved) {
  3970. sftk_CloseAllSessions(slot, PR_FALSE);
  3971. }
  3972. if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
  3973. PR_Sleep(loginWaitTime);
  3974. }
  3975. PR_Unlock(slot->pwCheckLock);
  3976. if (rv == SECSuccess) {
  3977. PZ_Lock(slot->slotLock);
  3978. /* make sure the login state matches the underlying
  3979. * database state */
  3980. slot->isLoggedIn = sftkdb_PWCached(handle) == SECSuccess ? PR_TRUE : PR_FALSE;
  3981. PZ_Unlock(slot->slotLock);
  3982. sftk_freeDB(handle);
  3983. handle = NULL;
  3984. /* update all sessions */
  3985. sftk_update_all_states(slot);
  3986. return CKR_OK;
  3987. }
  3988. crv = CKR_PIN_INCORRECT;
  3989. done:
  3990. if (handle) {
  3991. sftk_freeDB(handle);
  3992. }
  3993. return crv;
  3994. }
  3995. CK_RV
  3996. NSC_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
  3997. CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pUsername,
  3998. CK_ULONG ulUsernameLen)
  3999. {
  4000. /* softoken currently does not support additional users */
  4001. return CKR_OPERATION_NOT_INITIALIZED;
  4002. }
  4003. /* NSC_Logout logs a user out from a token. */
  4004. CK_RV
  4005. NSC_Logout(CK_SESSION_HANDLE hSession)
  4006. {
  4007. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  4008. SFTKSession *session;
  4009. SFTKDBHandle *handle;
  4010. CHECK_FORK();
  4011. if (slot == NULL) {
  4012. return CKR_SESSION_HANDLE_INVALID;
  4013. }
  4014. session = sftk_SessionFromHandle(hSession);
  4015. if (session == NULL)
  4016. return CKR_SESSION_HANDLE_INVALID;
  4017. sftk_FreeSession(session);
  4018. session = NULL;
  4019. if (!slot->isLoggedIn)
  4020. return CKR_USER_NOT_LOGGED_IN;
  4021. handle = sftk_getKeyDB(slot);
  4022. PZ_Lock(slot->slotLock);
  4023. slot->isLoggedIn = PR_FALSE;
  4024. slot->ssoLoggedIn = PR_FALSE;
  4025. if (slot->needLogin && handle) {
  4026. sftkdb_ClearPassword(handle);
  4027. }
  4028. PZ_Unlock(slot->slotLock);
  4029. if (handle) {
  4030. sftk_freeDB(handle);
  4031. }
  4032. sftk_update_all_states(slot);
  4033. return CKR_OK;
  4034. }
  4035. /*
  4036. * Create or remove a new slot on the fly.
  4037. * When creating a slot, "slot" is the slot that the request came from. The
  4038. * resulting slot will live in the same module as "slot".
  4039. * When removing a slot, "slot" is the slot to be removed.
  4040. * "object" is the creation object that specifies the module spec for the slot
  4041. * to add or remove.
  4042. */
  4043. static CK_RV
  4044. sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
  4045. SFTKObject *object)
  4046. {
  4047. PRBool isValidUserSlot = PR_FALSE;
  4048. PRBool isValidFIPSUserSlot = PR_FALSE;
  4049. PRBool isValidSlot = PR_FALSE;
  4050. PRBool isFIPS = PR_FALSE;
  4051. unsigned long moduleIndex = NSC_NON_FIPS_MODULE;
  4052. SFTKAttribute *attribute;
  4053. sftk_parameters paramStrings;
  4054. char *paramString;
  4055. CK_SLOT_ID slotID = 0;
  4056. SFTKSlot *newSlot = NULL;
  4057. CK_RV crv = CKR_OK;
  4058. if (class != CKO_NSS_DELSLOT && class != CKO_NSS_NEWSLOT) {
  4059. return CKR_ATTRIBUTE_VALUE_INVALID;
  4060. }
  4061. if (class == CKO_NSS_NEWSLOT && slot->slotID == FIPS_SLOT_ID) {
  4062. isFIPS = PR_TRUE;
  4063. }
  4064. attribute = sftk_FindAttribute(object, CKA_NSS_MODULE_SPEC);
  4065. if (attribute == NULL) {
  4066. return CKR_TEMPLATE_INCOMPLETE;
  4067. }
  4068. paramString = (char *)attribute->attrib.pValue;
  4069. crv = sftk_parseParameters(paramString, &paramStrings, isFIPS);
  4070. if (crv != CKR_OK) {
  4071. goto loser;
  4072. }
  4073. /* enforce only one at a time */
  4074. if (paramStrings.token_count != 1) {
  4075. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  4076. goto loser;
  4077. }
  4078. slotID = paramStrings.tokens[0].slotID;
  4079. /* stay within the valid ID space */
  4080. isValidUserSlot = (slotID >= SFTK_MIN_USER_SLOT_ID &&
  4081. slotID <= SFTK_MAX_USER_SLOT_ID);
  4082. isValidFIPSUserSlot = (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID &&
  4083. slotID <= SFTK_MAX_FIPS_USER_SLOT_ID);
  4084. if (class == CKO_NSS_DELSLOT) {
  4085. if (slot->slotID == slotID) {
  4086. isValidSlot = isValidUserSlot || isValidFIPSUserSlot;
  4087. }
  4088. } else {
  4089. /* only the crypto or FIPS slots can create new slot objects */
  4090. if (slot->slotID == NETSCAPE_SLOT_ID) {
  4091. isValidSlot = isValidUserSlot;
  4092. moduleIndex = NSC_NON_FIPS_MODULE;
  4093. } else if (slot->slotID == FIPS_SLOT_ID) {
  4094. isValidSlot = isValidFIPSUserSlot;
  4095. moduleIndex = NSC_FIPS_MODULE;
  4096. }
  4097. }
  4098. if (!isValidSlot) {
  4099. crv = CKR_ATTRIBUTE_VALUE_INVALID;
  4100. goto loser;
  4101. }
  4102. /* unload any existing slot at this id */
  4103. newSlot = sftk_SlotFromID(slotID, PR_TRUE);
  4104. if (newSlot && newSlot->present) {
  4105. crv = SFTK_ShutdownSlot(newSlot);
  4106. if (crv != CKR_OK) {
  4107. goto loser;
  4108. }
  4109. }
  4110. /* if we were just planning on deleting the slot, then do so now */
  4111. if (class == CKO_NSS_DELSLOT) {
  4112. /* sort of a unconventional use of this error code, be we are
  4113. * overusing CKR_ATTRIBUTE_VALUE_INVALID, and it does apply */
  4114. crv = newSlot ? CKR_OK : CKR_SLOT_ID_INVALID;
  4115. goto loser; /* really exit */
  4116. }
  4117. if (newSlot) {
  4118. crv = SFTK_SlotReInit(newSlot, paramStrings.configdir,
  4119. paramStrings.updatedir, paramStrings.updateID,
  4120. &paramStrings.tokens[0], moduleIndex);
  4121. } else {
  4122. crv = SFTK_SlotInit(paramStrings.configdir,
  4123. paramStrings.updatedir, paramStrings.updateID,
  4124. &paramStrings.tokens[0], moduleIndex);
  4125. }
  4126. loser:
  4127. sftk_freeParams(&paramStrings);
  4128. sftk_FreeAttribute(attribute);
  4129. return crv;
  4130. }
  4131. /* NSC_CreateObject creates a new object. */
  4132. CK_RV
  4133. NSC_CreateObject(CK_SESSION_HANDLE hSession,
  4134. CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
  4135. CK_OBJECT_HANDLE_PTR phObject)
  4136. {
  4137. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  4138. SFTKSession *session;
  4139. SFTKObject *object;
  4140. /* make sure class isn't randomly CKO_NSS_NEWSLOT or
  4141. * CKO_NETSCPE_DELSLOT. */
  4142. CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED;
  4143. CK_RV crv;
  4144. int i;
  4145. CHECK_FORK();
  4146. *phObject = CK_INVALID_HANDLE;
  4147. if (slot == NULL) {
  4148. return CKR_SESSION_HANDLE_INVALID;
  4149. }
  4150. /*
  4151. * now lets create an object to hang the attributes off of
  4152. */
  4153. object = sftk_NewObject(slot); /* fill in the handle later */
  4154. if (object == NULL) {
  4155. return CKR_HOST_MEMORY;
  4156. }
  4157. /*
  4158. * load the template values into the object
  4159. */
  4160. for (i = 0; i < (int)ulCount; i++) {
  4161. crv = sftk_AddAttributeType(object, sftk_attr_expand(&pTemplate[i]));
  4162. if (crv != CKR_OK) {
  4163. sftk_FreeObject(object);
  4164. return crv;
  4165. }
  4166. if ((pTemplate[i].type == CKA_CLASS) && pTemplate[i].pValue) {
  4167. class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
  4168. }
  4169. }
  4170. /* get the session */
  4171. session = sftk_SessionFromHandle(hSession);
  4172. if (session == NULL) {
  4173. sftk_FreeObject(object);
  4174. return CKR_SESSION_HANDLE_INVALID;
  4175. }
  4176. /*
  4177. * handle pseudo objects (CKO_NEWSLOT)
  4178. */
  4179. if ((class == CKO_NSS_NEWSLOT) || (class == CKO_NSS_DELSLOT)) {
  4180. crv = sftk_CreateNewSlot(slot, class, object);
  4181. goto done;
  4182. }
  4183. /*
  4184. * handle the base object stuff
  4185. */
  4186. crv = sftk_handleObject(object, session);
  4187. *phObject = object->handle;
  4188. done:
  4189. sftk_FreeSession(session);
  4190. sftk_FreeObject(object);
  4191. return crv;
  4192. }
  4193. /* NSC_CopyObject copies an object, creating a new object for the copy. */
  4194. CK_RV
  4195. NSC_CopyObject(CK_SESSION_HANDLE hSession,
  4196. CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
  4197. CK_OBJECT_HANDLE_PTR phNewObject)
  4198. {
  4199. SFTKObject *destObject, *srcObject;
  4200. SFTKSession *session;
  4201. CK_RV crv = CKR_OK;
  4202. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  4203. int i;
  4204. CHECK_FORK();
  4205. if (slot == NULL) {
  4206. return CKR_SESSION_HANDLE_INVALID;
  4207. }
  4208. /* Get srcObject so we can find the class */
  4209. session = sftk_SessionFromHandle(hSession);
  4210. if (session == NULL) {
  4211. return CKR_SESSION_HANDLE_INVALID;
  4212. }
  4213. srcObject = sftk_ObjectFromHandle(hObject, session);
  4214. if (srcObject == NULL) {
  4215. sftk_FreeSession(session);
  4216. return CKR_OBJECT_HANDLE_INVALID;
  4217. }
  4218. /*
  4219. * create an object to hang the attributes off of
  4220. */
  4221. destObject = sftk_NewObject(slot); /* fill in the handle later */
  4222. if (destObject == NULL) {
  4223. sftk_FreeSession(session);
  4224. sftk_FreeObject(srcObject);
  4225. return CKR_HOST_MEMORY;
  4226. }
  4227. /*
  4228. * load the template values into the object
  4229. */
  4230. for (i = 0; i < (int)ulCount; i++) {
  4231. if (sftk_modifyType(pTemplate[i].type, srcObject->objclass) == SFTK_NEVER) {
  4232. crv = CKR_ATTRIBUTE_READ_ONLY;
  4233. break;
  4234. }
  4235. crv = sftk_AddAttributeType(destObject, sftk_attr_expand(&pTemplate[i]));
  4236. if (crv != CKR_OK) {
  4237. break;
  4238. }
  4239. }
  4240. if (crv != CKR_OK) {
  4241. sftk_FreeSession(session);
  4242. sftk_FreeObject(srcObject);
  4243. sftk_FreeObject(destObject);
  4244. return crv;
  4245. }
  4246. /* sensitive can only be changed to CK_TRUE */
  4247. if (sftk_hasAttribute(destObject, CKA_SENSITIVE)) {
  4248. if (!sftk_isTrue(destObject, CKA_SENSITIVE)) {
  4249. sftk_FreeSession(session);
  4250. sftk_FreeObject(srcObject);
  4251. sftk_FreeObject(destObject);
  4252. return CKR_ATTRIBUTE_READ_ONLY;
  4253. }
  4254. }
  4255. /*
  4256. * now copy the old attributes from the new attributes
  4257. */
  4258. /* don't create a token object if we aren't in a rw session */
  4259. /* we need to hold the lock to copy a consistant version of
  4260. * the object. */
  4261. crv = sftk_CopyObject(destObject, srcObject);
  4262. destObject->objclass = srcObject->objclass;
  4263. sftk_FreeObject(srcObject);
  4264. if (crv != CKR_OK) {
  4265. sftk_FreeObject(destObject);
  4266. sftk_FreeSession(session);
  4267. return crv;
  4268. }
  4269. crv = sftk_handleObject(destObject, session);
  4270. *phNewObject = destObject->handle;
  4271. sftk_FreeSession(session);
  4272. sftk_FreeObject(destObject);
  4273. return crv;
  4274. }
  4275. /* NSC_GetObjectSize gets the size of an object in bytes. */
  4276. CK_RV
  4277. NSC_GetObjectSize(CK_SESSION_HANDLE hSession,
  4278. CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
  4279. {
  4280. CHECK_FORK();
  4281. *pulSize = 0;
  4282. return CKR_OK;
  4283. }
  4284. static CK_RV
  4285. nsc_GetTokenAttributeValue(SFTKSession *session, CK_OBJECT_HANDLE hObject,
  4286. CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
  4287. {
  4288. SFTKSlot *slot = sftk_SlotFromSession(session);
  4289. SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, hObject);
  4290. SFTKDBHandle *keydb = NULL;
  4291. CK_RV crv;
  4292. if (dbHandle == NULL) {
  4293. return CKR_OBJECT_HANDLE_INVALID;
  4294. }
  4295. crv = sftkdb_GetAttributeValue(dbHandle, hObject, pTemplate, ulCount);
  4296. /* make sure we don't export any sensitive information */
  4297. keydb = sftk_getKeyDB(slot);
  4298. if (dbHandle == keydb) {
  4299. CK_ULONG i;
  4300. for (i = 0; i < ulCount; i++) {
  4301. if (sftk_isSensitive(pTemplate[i].type, CKO_PRIVATE_KEY)) {
  4302. crv = CKR_ATTRIBUTE_SENSITIVE;
  4303. if (pTemplate[i].pValue && (pTemplate[i].ulValueLen != -1)) {
  4304. PORT_Memset(pTemplate[i].pValue, 0,
  4305. pTemplate[i].ulValueLen);
  4306. }
  4307. pTemplate[i].ulValueLen = -1;
  4308. }
  4309. }
  4310. }
  4311. sftk_freeDB(dbHandle);
  4312. if (keydb) {
  4313. sftk_freeDB(keydb);
  4314. }
  4315. return crv;
  4316. }
  4317. /* NSC_GetAttributeValue obtains the value of one or more object attributes. */
  4318. CK_RV
  4319. NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
  4320. CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
  4321. {
  4322. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  4323. SFTKSession *session;
  4324. SFTKObject *object;
  4325. SFTKAttribute *attribute;
  4326. PRBool sensitive;
  4327. CK_RV crv;
  4328. int i;
  4329. CHECK_FORK();
  4330. if (slot == NULL) {
  4331. return CKR_SESSION_HANDLE_INVALID;
  4332. }
  4333. /*
  4334. * make sure we're allowed
  4335. */
  4336. session = sftk_SessionFromHandle(hSession);
  4337. if (session == NULL) {
  4338. return CKR_SESSION_HANDLE_INVALID;
  4339. }
  4340. /* short circuit everything for token objects */
  4341. if (sftk_isToken(hObject)) {
  4342. crv = nsc_GetTokenAttributeValue(session, hObject, pTemplate, ulCount);
  4343. sftk_FreeSession(session);
  4344. return crv;
  4345. }
  4346. /* handle the session object */
  4347. object = sftk_ObjectFromHandle(hObject, session);
  4348. sftk_FreeSession(session);
  4349. if (object == NULL) {
  4350. return CKR_OBJECT_HANDLE_INVALID;
  4351. }
  4352. /* don't read a private object if we aren't logged in */
  4353. if ((!slot->isLoggedIn) && (slot->needLogin) &&
  4354. (sftk_isTrue(object, CKA_PRIVATE))) {
  4355. sftk_FreeObject(object);
  4356. return CKR_USER_NOT_LOGGED_IN;
  4357. }
  4358. crv = CKR_OK;
  4359. sensitive = sftk_isTrue(object, CKA_SENSITIVE);
  4360. for (i = 0; i < (int)ulCount; i++) {
  4361. /* Make sure that this attribute is retrievable */
  4362. if (sensitive && sftk_isSensitive(pTemplate[i].type, object->objclass)) {
  4363. crv = CKR_ATTRIBUTE_SENSITIVE;
  4364. pTemplate[i].ulValueLen = -1;
  4365. continue;
  4366. }
  4367. attribute = sftk_FindAttribute(object, pTemplate[i].type);
  4368. if (attribute == NULL) {
  4369. crv = CKR_ATTRIBUTE_TYPE_INVALID;
  4370. pTemplate[i].ulValueLen = -1;
  4371. continue;
  4372. }
  4373. if (pTemplate[i].pValue != NULL) {
  4374. PORT_Memcpy(pTemplate[i].pValue, attribute->attrib.pValue,
  4375. attribute->attrib.ulValueLen);
  4376. }
  4377. pTemplate[i].ulValueLen = attribute->attrib.ulValueLen;
  4378. sftk_FreeAttribute(attribute);
  4379. }
  4380. sftk_FreeObject(object);
  4381. return crv;
  4382. }
  4383. /* NSC_SetAttributeValue modifies the value of one or more object attributes */
  4384. CK_RV
  4385. NSC_SetAttributeValue(CK_SESSION_HANDLE hSession,
  4386. CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
  4387. {
  4388. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  4389. SFTKSession *session;
  4390. SFTKAttribute *attribute;
  4391. SFTKObject *object;
  4392. PRBool isToken;
  4393. CK_RV crv = CKR_OK;
  4394. CK_BBOOL legal;
  4395. int i;
  4396. CHECK_FORK();
  4397. if (slot == NULL) {
  4398. return CKR_SESSION_HANDLE_INVALID;
  4399. }
  4400. /*
  4401. * make sure we're allowed
  4402. */
  4403. session = sftk_SessionFromHandle(hSession);
  4404. if (session == NULL) {
  4405. return CKR_SESSION_HANDLE_INVALID;
  4406. }
  4407. object = sftk_ObjectFromHandle(hObject, session);
  4408. if (object == NULL) {
  4409. sftk_FreeSession(session);
  4410. return CKR_OBJECT_HANDLE_INVALID;
  4411. }
  4412. /* don't modify a private object if we aren't logged in */
  4413. if ((!slot->isLoggedIn) && (slot->needLogin) &&
  4414. (sftk_isTrue(object, CKA_PRIVATE))) {
  4415. sftk_FreeSession(session);
  4416. sftk_FreeObject(object);
  4417. return CKR_USER_NOT_LOGGED_IN;
  4418. }
  4419. /* don't modify a token object if we aren't in a rw session */
  4420. isToken = sftk_isTrue(object, CKA_TOKEN);
  4421. if (((session->info.flags & CKF_RW_SESSION) == 0) && isToken) {
  4422. sftk_FreeSession(session);
  4423. sftk_FreeObject(object);
  4424. return CKR_SESSION_READ_ONLY;
  4425. }
  4426. sftk_FreeSession(session);
  4427. /* only change modifiable objects */
  4428. if (!sftk_isTrue(object, CKA_MODIFIABLE)) {
  4429. sftk_FreeObject(object);
  4430. return CKR_ATTRIBUTE_READ_ONLY;
  4431. }
  4432. for (i = 0; i < (int)ulCount; i++) {
  4433. /* Make sure that this attribute is changeable */
  4434. switch (sftk_modifyType(pTemplate[i].type, object->objclass)) {
  4435. case SFTK_NEVER:
  4436. case SFTK_ONCOPY:
  4437. default:
  4438. crv = CKR_ATTRIBUTE_READ_ONLY;
  4439. break;
  4440. case SFTK_SENSITIVE:
  4441. legal = (pTemplate[i].type == CKA_EXTRACTABLE) ? CK_FALSE : CK_TRUE;
  4442. if ((*(CK_BBOOL *)pTemplate[i].pValue) != legal) {
  4443. crv = CKR_ATTRIBUTE_READ_ONLY;
  4444. }
  4445. break;
  4446. case SFTK_ALWAYS:
  4447. break;
  4448. }
  4449. if (crv != CKR_OK)
  4450. break;
  4451. /* find the old attribute */
  4452. attribute = sftk_FindAttribute(object, pTemplate[i].type);
  4453. if (attribute == NULL) {
  4454. crv = CKR_ATTRIBUTE_TYPE_INVALID;
  4455. break;
  4456. }
  4457. sftk_FreeAttribute(attribute);
  4458. crv = sftk_forceAttribute(object, sftk_attr_expand(&pTemplate[i]));
  4459. if (crv != CKR_OK)
  4460. break;
  4461. }
  4462. sftk_FreeObject(object);
  4463. return crv;
  4464. }
  4465. static CK_RV
  4466. sftk_expandSearchList(SFTKSearchResults *search, int count)
  4467. {
  4468. search->array_size += count;
  4469. search->handles = (CK_OBJECT_HANDLE *)PORT_Realloc(search->handles,
  4470. sizeof(CK_OBJECT_HANDLE) * search->array_size);
  4471. return search->handles ? CKR_OK : CKR_HOST_MEMORY;
  4472. }
  4473. static CK_RV
  4474. sftk_searchDatabase(SFTKDBHandle *handle, SFTKSearchResults *search,
  4475. const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
  4476. {
  4477. CK_RV crv;
  4478. int objectListSize = search->array_size - search->size;
  4479. CK_OBJECT_HANDLE *array = &search->handles[search->size];
  4480. SDBFind *find;
  4481. CK_ULONG count;
  4482. crv = sftkdb_FindObjectsInit(handle, pTemplate, ulCount, &find);
  4483. if (crv != CKR_OK)
  4484. return crv;
  4485. do {
  4486. crv = sftkdb_FindObjects(handle, find, array, objectListSize, &count);
  4487. if ((crv != CKR_OK) || (count == 0))
  4488. break;
  4489. search->size += count;
  4490. objectListSize -= count;
  4491. if (objectListSize > 0)
  4492. break;
  4493. crv = sftk_expandSearchList(search, NSC_SEARCH_BLOCK_SIZE);
  4494. objectListSize = NSC_SEARCH_BLOCK_SIZE;
  4495. array = &search->handles[search->size];
  4496. } while (crv == CKR_OK);
  4497. sftkdb_FindObjectsFinal(handle, find);
  4498. return crv;
  4499. }
  4500. /* softoken used to search the SMimeEntries automatically instead of
  4501. * doing this in pk11wrap. This code should really be up in
  4502. * pk11wrap so that it will work with other tokens other than softoken.
  4503. */
  4504. CK_RV
  4505. sftk_emailhack(SFTKSlot *slot, SFTKDBHandle *handle,
  4506. SFTKSearchResults *search, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
  4507. {
  4508. PRBool isCert = PR_FALSE;
  4509. int emailIndex = -1;
  4510. unsigned int i;
  4511. SFTKSearchResults smime_search;
  4512. CK_ATTRIBUTE smime_template[2];
  4513. CK_OBJECT_CLASS smime_class = CKO_NSS_SMIME;
  4514. SFTKAttribute *attribute = NULL;
  4515. SFTKObject *object = NULL;
  4516. CK_RV crv = CKR_OK;
  4517. smime_search.handles = NULL; /* paranoia, some one is bound to add a goto
  4518. * loser before this gets initialized */
  4519. /* see if we are looking for email certs */
  4520. for (i = 0; i < ulCount; i++) {
  4521. if (pTemplate[i].type == CKA_CLASS) {
  4522. if ((pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS) ||
  4523. (*(CK_OBJECT_CLASS *)pTemplate[i].pValue) != CKO_CERTIFICATE)) {
  4524. /* not a cert, skip out */
  4525. break;
  4526. }
  4527. isCert = PR_TRUE;
  4528. } else if (pTemplate[i].type == CKA_NSS_EMAIL) {
  4529. emailIndex = i;
  4530. }
  4531. if (isCert && (emailIndex != -1))
  4532. break;
  4533. }
  4534. if (!isCert || (emailIndex == -1)) {
  4535. return CKR_OK;
  4536. }
  4537. /* we are doing a cert and email search, find the SMimeEntry */
  4538. smime_template[0].type = CKA_CLASS;
  4539. smime_template[0].pValue = &smime_class;
  4540. smime_template[0].ulValueLen = sizeof(smime_class);
  4541. smime_template[1] = pTemplate[emailIndex];
  4542. smime_search.handles = (CK_OBJECT_HANDLE *)
  4543. PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
  4544. if (smime_search.handles == NULL) {
  4545. crv = CKR_HOST_MEMORY;
  4546. goto loser;
  4547. }
  4548. smime_search.index = 0;
  4549. smime_search.size = 0;
  4550. smime_search.array_size = NSC_SEARCH_BLOCK_SIZE;
  4551. crv = sftk_searchDatabase(handle, &smime_search, smime_template, 2);
  4552. if (crv != CKR_OK || smime_search.size == 0) {
  4553. goto loser;
  4554. }
  4555. /* get the SMime subject */
  4556. object = sftk_NewTokenObject(slot, NULL, smime_search.handles[0]);
  4557. if (object == NULL) {
  4558. crv = CKR_HOST_MEMORY; /* is there any other reason for this failure? */
  4559. goto loser;
  4560. }
  4561. attribute = sftk_FindAttribute(object, CKA_SUBJECT);
  4562. if (attribute == NULL) {
  4563. crv = CKR_ATTRIBUTE_TYPE_INVALID;
  4564. goto loser;
  4565. }
  4566. /* now find the certs with that subject */
  4567. pTemplate[emailIndex] = attribute->attrib;
  4568. /* now add the appropriate certs to the search list */
  4569. crv = sftk_searchDatabase(handle, search, pTemplate, ulCount);
  4570. pTemplate[emailIndex] = smime_template[1]; /* restore the user's template*/
  4571. loser:
  4572. if (attribute) {
  4573. sftk_FreeAttribute(attribute);
  4574. }
  4575. if (object) {
  4576. sftk_FreeObject(object);
  4577. }
  4578. if (smime_search.handles) {
  4579. PORT_Free(smime_search.handles);
  4580. }
  4581. return crv;
  4582. }
  4583. static void
  4584. sftk_pruneSearch(CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount,
  4585. PRBool *searchCertDB, PRBool *searchKeyDB)
  4586. {
  4587. CK_ULONG i;
  4588. *searchCertDB = PR_TRUE;
  4589. *searchKeyDB = PR_TRUE;
  4590. for (i = 0; i < ulCount; i++) {
  4591. if (pTemplate[i].type == CKA_CLASS && pTemplate[i].pValue != NULL) {
  4592. CK_OBJECT_CLASS class = *((CK_OBJECT_CLASS *)pTemplate[i].pValue);
  4593. if (class == CKO_PRIVATE_KEY || class == CKO_SECRET_KEY) {
  4594. *searchCertDB = PR_FALSE;
  4595. } else {
  4596. *searchKeyDB = PR_FALSE;
  4597. }
  4598. break;
  4599. }
  4600. }
  4601. }
  4602. static CK_RV
  4603. sftk_searchTokenList(SFTKSlot *slot, SFTKSearchResults *search,
  4604. CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount,
  4605. PRBool isLoggedIn)
  4606. {
  4607. CK_RV crv = CKR_OK;
  4608. CK_RV crv2;
  4609. PRBool searchCertDB;
  4610. PRBool searchKeyDB;
  4611. sftk_pruneSearch(pTemplate, ulCount, &searchCertDB, &searchKeyDB);
  4612. if (searchCertDB) {
  4613. SFTKDBHandle *certHandle = sftk_getCertDB(slot);
  4614. crv = sftk_searchDatabase(certHandle, search, pTemplate, ulCount);
  4615. crv2 = sftk_emailhack(slot, certHandle, search, pTemplate, ulCount);
  4616. if (crv == CKR_OK)
  4617. crv = crv2;
  4618. sftk_freeDB(certHandle);
  4619. }
  4620. if (crv == CKR_OK && isLoggedIn && searchKeyDB) {
  4621. SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
  4622. crv = sftk_searchDatabase(keyHandle, search, pTemplate, ulCount);
  4623. sftk_freeDB(keyHandle);
  4624. }
  4625. return crv;
  4626. }
  4627. /* NSC_FindObjectsInit initializes a search for token and session objects
  4628. * that match a template. */
  4629. CK_RV
  4630. NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
  4631. CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
  4632. {
  4633. SFTKSearchResults *search = NULL, *freeSearch = NULL;
  4634. SFTKSession *session = NULL;
  4635. SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
  4636. CK_RV crv = CKR_OK;
  4637. PRBool isLoggedIn;
  4638. CHECK_FORK();
  4639. if (slot == NULL) {
  4640. return CKR_SESSION_HANDLE_INVALID;
  4641. }
  4642. session = sftk_SessionFromHandle(hSession);
  4643. if (session == NULL) {
  4644. crv = CKR_SESSION_HANDLE_INVALID;
  4645. goto loser;
  4646. }
  4647. search = (SFTKSearchResults *)PORT_Alloc(sizeof(SFTKSearchResults));
  4648. if (search == NULL) {
  4649. crv = CKR_HOST_MEMORY;
  4650. goto loser;
  4651. }
  4652. search->handles = (CK_OBJECT_HANDLE *)
  4653. PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
  4654. if (search->handles == NULL) {
  4655. crv = CKR_HOST_MEMORY;
  4656. goto loser;
  4657. }
  4658. search->index = 0;
  4659. search->size = 0;
  4660. search->array_size = NSC_SEARCH_BLOCK_SIZE;
  4661. isLoggedIn = (PRBool)((!slot->needLogin) || slot->isLoggedIn);
  4662. crv = sftk_searchTokenList(slot, search, pTemplate, ulCount, isLoggedIn);
  4663. if (crv != CKR_OK) {
  4664. goto loser;
  4665. }
  4666. /* build list of found objects in the session */
  4667. crv = sftk_searchObjectList(search, slot->sessObjHashTable,
  4668. slot->sessObjHashSize, slot->objectLock,
  4669. pTemplate, ulCount, isLoggedIn);
  4670. if (crv != CKR_OK) {
  4671. goto loser;
  4672. }
  4673. if ((freeSearch = session->search) != NULL) {
  4674. session->search = NULL;
  4675. sftk_FreeSearch(freeSearch);
  4676. }
  4677. session->search = search;
  4678. sftk_FreeSession(session);
  4679. return CKR_OK;
  4680. loser:
  4681. if (search) {
  4682. sftk_FreeSearch(search);
  4683. }
  4684. if (session) {
  4685. sftk_FreeSession(session);
  4686. }
  4687. return crv;
  4688. }
  4689. /* NSC_FindObjects continues a search for token and session objects
  4690. * that match a template, obtaining additional object handles. */
  4691. CK_RV
  4692. NSC_FindObjects(CK_SESSION_HANDLE hSession,
  4693. CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount,
  4694. CK_ULONG_PTR pulObjectCount)
  4695. {
  4696. SFTKSession *session;
  4697. SFTKSearchResults *search;
  4698. int transfer;
  4699. int left;
  4700. CHECK_FORK();
  4701. *pulObjectCount = 0;
  4702. session = sftk_SessionFromHandle(hSession);
  4703. if (session == NULL)
  4704. return CKR_SESSION_HANDLE_INVALID;
  4705. if (session->search == NULL) {
  4706. sftk_FreeSession(session);
  4707. return CKR_OK;
  4708. }
  4709. search = session->search;
  4710. left = session->search->size - session->search->index;
  4711. transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount;
  4712. if (transfer > 0) {
  4713. PORT_Memcpy(phObject, &search->handles[search->index],
  4714. transfer * sizeof(CK_OBJECT_HANDLE));
  4715. } else {
  4716. *phObject = CK_INVALID_HANDLE;
  4717. }
  4718. search->index += transfer;
  4719. if (search->index == search->size) {
  4720. session->search = NULL;
  4721. sftk_FreeSearch(search);
  4722. }
  4723. *pulObjectCount = transfer;
  4724. sftk_FreeSession(session);
  4725. return CKR_OK;
  4726. }
  4727. /* NSC_FindObjectsFinal finishes a search for token and session objects. */
  4728. CK_RV
  4729. NSC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
  4730. {
  4731. SFTKSession *session;
  4732. SFTKSearchResults *search;
  4733. CHECK_FORK();
  4734. session = sftk_SessionFromHandle(hSession);
  4735. if (session == NULL)
  4736. return CKR_SESSION_HANDLE_INVALID;
  4737. search = session->search;
  4738. session->search = NULL;
  4739. sftk_FreeSession(session);
  4740. if (search != NULL) {
  4741. sftk_FreeSearch(search);
  4742. }
  4743. return CKR_OK;
  4744. }
  4745. CK_RV
  4746. NSC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
  4747. CK_VOID_PTR pReserved)
  4748. {
  4749. CHECK_FORK();
  4750. return CKR_FUNCTION_NOT_SUPPORTED;
  4751. }