BOBOdHHHHHH`H@B  -ZPerry The CynicfBLOM!`oDxHH(FG(HH(d'` l/h82h  4e _ DSET_ :H? lhdpo)t 3o.c ot,C6&To&2gcBFm  S h 3 S 1Aa]wseh $5S"#"#$q&T&l() *K**,.{/122345u5689}:H B          *        < I        8 E                     W  k  A  Q  S h  x      3 S    .        +             1 A l        ^ b     ) 6 % D ] w            h     : I     $ 4            5       %            [ `   C M X h       !         "# # # # $ $ $ $ $ $ %O %Y %j %z % % % % % % & & & &% &+ &0 &T &l & & & & & & ' '2 's ' ' ' ' ' (1 (> (C (P ( ( ( )  * * , ,  ,  , , ,  , , -% -- . . . . . . . . / /' / / 0 0  1 1  2? 2N 3G 3M 3 3 4V 4Z 4x 4 4 4 5[ 5j 5u5 5 5 5 6 6 7 7 7$ 9 9 z` n#*aN(=xtTX P'H!L^0^" &*.(246I$How to Write a CSSM CSP in C++ (CSP Plugins for Very Lazy People) Warning: This document is incomplete. Before relying on anything here, talk to Perry. Be sure to read the document, How to Write a Plugin, before this. It explains how the SPI translation layer embeds plugins written in C++ into the standard CSSM SPI plugin environment. This document is specifically about writing a CSP (Cryptographic Service Provider) plugin module. How Does It Work? Remember that the SPI transition layer (glue) defines two C++ classes: CssmPlugin and PluginSession. These are not specific to a particular type of plugin. You must create a subclass of CssmPlugin to represent your module, and a subclass of PluginSession to implement an attachment (session) of your module. The CSPsession.h header file provides you with two subclasses of PluginSession that you can inherit from to implement your CSP session object: CSPPluginSession and CSPFullPluginSession. The choice is yours. Using CSPPluginSession The CSPPluginSession class provides a bit of CSP specific helpers on top of the common PluginSession features, but not very much. Most SPI functions are still pure virtual in this class, and you must implement them in your session class derived from CSPPluginSession. CSPPluginSession provides the following features: Basic Cryptographic Context management Context Notification event dispatching Login state management Using CSPFullPluginSession CSPFullPluginSession is a subclass of CSPPluginSession, and thus provides all facilities of that class. In addition, it implements all methods required of a CSP session object. The implementation of most operations is transferred to methods of the CSPContext class, a subclass of PluginContext from which all your context objects must inherit. In the CSPFullPluginSession environment, your context objects are not passive data, but are the carriers of algorithmic operations. They are not optional; you must have context objects for all cryptographic operations. Different types of cryptographic operations call different methods of the context object with specific semantics. In exchange, most problems common to CSP operation are managed by CSPFullPluginSession, including buffer management, staging control, and much of the framing/unframing of data, key, and related structures. As a rule of thumb, complex CSP modules probably want to derive from CSPFullPluginSession unless they have very unusual implementation strategies. Very simple, special purpose CSPs (which only a few cryptographic operations implemented) are smaller, and may be easier, if implemented directly on top of CSPPluginSession. Managing Login State CSPPluginSession maintains a login bit indicating whether your CSP has been successfully logged into. The bit is under your control, using the loggedIn methods to set or get it. This is quite trivial. Managing Cryptographic Contexts Most CSP modules need to create local data that shadows the cryptographic context objects maintained by CSSM. Typically, these SPI context objects hold cryptographic state of varying sorts. In the CSPFullPluginSession environment, context objects also carry the cryptographic implementation methods. The CSP SPI interface contains an EventNotify method that CSSM calls to notify the plugin of the creation, modification, and deletion of context objects. CSPPluginSession fully implements this method and maintains a dictionary of context state objects. You may (but need not) implement the methods contextCreate, contextUpdate, and contextDelete. These methods are called at appropriate times to help maintain your context objects. Context Objects All your context objects must inherit from CSPPluginSession::PluginContext. Your context objects may contain any data you like, and can implement any number of methods. It is common to have different subclasses to model different types of CSSM contexts, but this is completely up to you. There is one virtual method in PluginContext. By default, the changed method is called when CSSM tries to modify an existing context on behalf of a user . Your implementation of changed should make any desired changes to your context object and return true to indicate that should continue to be used, or return false to request that the context object be deleted. Your contextCreate Method When CSSM wants to create a context on behalf of a caller, your contextCreate method is called with the context handle and CSSM Context object. If you find that you want to create a context object to shadow CSSMs, you may create it here and return it as a function result. Your context object must be a subclass of CSPPluginSession::PluginContext. If you dont need any shadow context or want to create it later, just return NULL (which is the default behavior). If you throw an exception, your plugin will communicate that error to CSSM, which will accordingly reject the callers attempt to create the cryptographic context. Your contextUpdate Method ContextUpdate is ca'lled whenever a caller asks CSSM to modify a context. You are presented with the CSSM context handle and both CSSMs and your context object (NULL if you did not create one earlier). After examining CSSMs context object (which contains any modifications attempted by the user), you may either update your context object accordingly, or throw an exception. If you throw an exception, CSSM will reject the callers attempt to modify the context, and the CSSM context will remain unchanged. Note that your contextUpdate method can delete an existing con!text object and replace it with a new one (possibly of a different class). This allows you to adapt to user context changes by changing the implementation of your context object. The default implementation of contextUpdate will call the context objects changed method and respond accordingly. Note that if you override contextUpdate, this behavior will not take place (unless you explicitly invoke it by calling the inherited behavior). Your contextDelete Method ContextDelete is called whenever a caller asks CSSM to delete a context. You may^ do whatever you like in this method. However, after contextDelete finishes, the context object will be unconditionally deleted. There is no way to prevent this: even if you throw an exception from within contextDelete, the context object will be deleted before the error you threw is communicated back to CSSM. SetContext and getContext CSPPluginSession keeps a dictionary of your context objects, indexed by the CSSM_CC_HANDLE of their CSSM-side sibling. It also provides methods setContext and getContext to read and change this dictionary. GetContext is a template function, allowing you to safely retrieve any class of context object. You can remove an object from the collection by calling setContext with a NULL argument. These calls are safe to make at any time, and allow you to implement arbitrary context management strategies. How to Put It All Toge^ther The context management system is designed to be general and flexible. There are several ways you can use it. Obviously, you can ignore the whole matter. By default, contextCreate will not create contexts, and contextUpdate and contextDelete will never be called. This works well for simple modules that need keep no context for their operations. You can use contextCreate to create context objects and implement their changed method and/or the contextUpdate method to keep them current during user changes. This works well if you can determine the class of context object used at creation time, and you know how to update your objects when the user makes changes. In this case, you need not override contextDelete (and possibly contextUpdate); you can clean up any context state in its destructor. You can defer creation of context objects until you absolutely need them. Leave contextCreate alone, and there will be no context object until you explicitly make one, usually when an actual cryptographic operation begins. Remember to call setContext to notify CSPPluginSession of your creation. Your context will still be automatically deleted when CSSM is through with it. Note that the default behavior or contextUpdate is to call the context objects changed method. This allows you to respond to some changes by updating your object, while dealing with more complicated cases by requesting deletion of the object . The default action of changed is to always return false, so that any attempt to modify a context through CSSM causes your context object to be deleted. Combined with the lazy creation method above, this allows you to reuse contexts safely for sequences of like operations, while having them automatically updated or deleted when the circumstances change. Needless to say, whatever context management strategy you choose for your plugin, you are well advised to stick with it. Trying to mix strategies is bound to lead to confusion, not least your own. Using CSPFullPluginSession CSPFullPluginSession implements all methods required of a CSP plugin module. Your subclass of it need not redefine any of these, though of course you can. Beware of overriding some but not all of a related group of CSSM operations - their implementation in CSPFullPluginSession probably assumes that they cooperate peacefully to maintain CSSM conforming operation. The central feature of the CSPFullPluginSession environment is the CSPContext class, a subclass of PluginContext. CSPFullPluginSession disects CSSM-level operations into sequences of simpler operations that are methods of CSPContext. For example, a CSSM_EncryptData call invokes CSPFullPluginSessions EncryptData method, which in turn will call your setupContext method to prepare a context object, then call the contexts init, update, and final methods to perform the encryption. The setupContext Method One important session method added by CSPFullPluginSession is setupContext. SetupContext is called immediately before a context is taken into active use by a CSSM operation. This is your last chance to create or update a context object as late as possible - when setupContext returns, there must be a valid context ready for use, or an internal error is triggered. By default, setupContext does nothing. Thus, you must implement this method unless your contextCreate and contextUpdate methods ensure that the context is already prepared. As in contextUpdate, you are entitled to delete any existing context and replace it with a new one if you wish. Your CSPContext Class Your context object must implement a set of virtual methods defined by its CSPContext parent. Which methods exactly to implement depends on the class of operation your object provides. The default implementations of CSPContexts virtual methods generate an internal error, so you will notice quickly if you forget one. Here is an overview of the operational methods of CSPContext:  Init is always called with two arguments. The first is the CSSM context object with all the values you may need. The second one is a bool that is true if the operation is an encoding one - encryption, signing, etc., and false if it is decoding (decryption, verifying, etc.) For operation types that dont have such natural pairs the value is true and should be ignored. The update, final, and generate methods are overloaded for different operand types. All data arguments are in terms of references to CssmData objects. Const objects denote inputs; non-const objects denote outputs. There are no in-out type arguments used in this interface, except that output CssmData arguments have their length fields adjusted downwards to indicate actual size of output generated. Note that different encoding directions may use different method signatures; for example, generating signatures uses final with a non-const (output) argument, while verifying signatures takes a const (input) argument and verifies it. The outputSize, inputSize, and minimumProgress methods help CSPFullPluginSession manage its buffers. With the exception of encryption/decryption algorithms, only outputSize is called, and only with zero and true arguments (requesting final output size). This should return a reasonable upper bound on the amount of output generated by a call to final. For encryption/decryption algorithms, outputSize should calculate a reasonable upper bound on the size of an output buffer required to process the amount of input indicated. If the final argument is true, this is a final output call, and any trailing padding should be included in the estimate. Correspondingly, the inputSize method should return a nonzero lower bound on the amount of input the algorithm can consume given the size of an output buffer. Return zero only if no progress can be made given the output buffer size (e.g. because the output size is too small for a full block of output). Finally, the minimumProgress method is used during encryption/decryption to inquire what minimum sizes of input and output buffers are needed for the algorithm to make progress, typically by processing a complete block or unit of input. The contract is essentially that if the update method is presented with that much input and given at least that much output buffer, it will produce output. The generate methods cover special cases such as key and algorithm generation that do not fit the standard pattern. For algorithm types that use generate, init is called first, followed by generate. None of the other methods are used in that case. The clone method should allocate and return a copy of the context object. Do not add the copy into the context dictionary. This is currently only used to implement the DigestDataClone function. Using AlgorithmFactorys A particular class, CSPFullPluginSession::AlgorithmFactory, is available to modularize different sources of algorithm implementations. This is a very simple facility, primarily useful for CSP modules that implement different algorithms from different algorithmic libraries or sources. It works like this: For each source of algorithm implementations, make a subclass of AlgorithmFactory. Implement its setup method. In setup, examine the CSSM cryptographic context passed in and determine whether you can support this kind of operation. If you do, create a context object, assign it to the ctx argument, and return true. This indicates that you have taken responsibility for the operation. Otherwise return false, indicating that you cannot support this operation. In the setupContext method of your session object, you can now simply call the setup methods of your various algorithm sources in some convenient order, until one returns true, indicating that it wants to support the CSSM context in question. Note that the use of AlgorithmFactory objects is completely optional and not related to any other features of the CSP support framework. If this mechanism does not fit your requirements, just ignore it. ZN DSETTY`YH   ; ? N  ZZ That is, the user called the CSSM_UpdateContextAttributes or CSSM_SetContext functions.DSETT?^`_0  ? ^  ` ` Of course the new context object must still be a subclass of CSPPluginSession::PluginContext.DSETTG`G   HH That is, they are properly interlocked against multi-threaded access.DSETT`0      by returning false.DSETT`    For example, it is inadvisable to override an *Init function without also overriding the corresponding *Update and *Final methods.DSET.H2"0L6*DSET0 Htpx+{$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ *lh*(,  RCTAB  COLMCHNK x$D.\ Latin init update final Methodgenerate inputSize inputSizeeminimumProgress outputSize@ clone COLM|CHNK `6`Usehaa"Initialize the context object Perform one operation step.)Finalize the algorithm and deliver result"Parameter and key generationestimate output data sizeestimate input data size>9provide minimum input/output data needed to make progressJEprovide minimum input/output data needed to make algorithmic progress make a copy of the context61Initialize the context object from a CSSM_CONTEXT,'make an independent copy of the contextL DSETT.H dx`\6*lx\LDSET.H XZ  6*ZDSET:.H 6T Z  6*ZDSUM(Perry The CynicHDNISTYLIdDSTYLD@80( 0 %      2 8    !     4       o    %000000 0 0 0 0 0 0!!0%""##0""$$0""%%0""&&0"$''0"$((0"$ ))0"$ **0"$ ++0"$ ,,0"#--0"#..0"%!//0"%%00110002200033000440025500266002 77002 88002 99002 ::001 ;;001 <<003==003%>>??0>>!@@0>> AA0>>!BB0>@"" CC0>@#DD0>@$ EE0>@% FF0>@& GG0>@' HH0>?#( II0>?#) JJ0>A* KK0>A+%LL,MM0LL$-NN0LL.OO0LL/ PP0LN0QQ0LN1RR0LN2SS0LN3TT0LN4UU0LN5VV0LM%: WW0LM%; XX0LO8 YY0LO9 ZZ,[[0ZZ- N\\0ZZ.]]0ZZ<^^0Z\0__0Z\=``0Z\>aa0Z\?bb0Z\@cc0Z[&: dd0Z]Aee Bff0ee'Cgg0ee Dhh0eg $ii0eg %jj0eg &kk0eg 'll0ef(Gmm0ef(Hnn oo8nn pp8nn qq8nn rr8nn ss8nn tt8nn uu8nn vv8nn ww8nn xx8nn yy8nn zz8nn {{)||8{{*}}8{{+~~8{{,8{{-8{{- 8{{-!8{{-"8{{-#8{{-$8{{-%  &8 '8 (8 )8 *8 +  .,.,     t _4435/0261  7,7,0-!    . . 33 /5 /51519: 9=7<>6?E;EAF @6@6HASH $ ()( ( ( ( ) (ô׌Lô،Z/("0Ҵ"<"%8e>n:7(( * *QQA,Qv * + ,oQpvqrst u */vTwyxyz,8|QI}v4~555 5 /5 T5 y5 +$'()*+/0 OHPICU, - 06 17 28 39CcJVKW (2 G. 5&y<y:?; H=%B4 $3 35J?> EM>[1#g-D.E/F0GFJ`B/R0S1T2U0YJX&C.K "@ #A $\ %]jkhi*lmHd/Q9a:b1^7_8`DP0f'O% & C 0$C 0(I)01L:Qfeg{hmhiCodjaqit rl tuzoz}Bod}n>B CHAR<    7  "     77"   " ( ' %         .     / * 2 !/  $  '& &  & )&     3   7    =   >   00HASH (0,1-4*E+<8"&3: ;#D")*  )% * ? 5  ; A 3624FH6L R /   9:0$/1@7.  I CELL4(,'          x $ x                ( s EHASH!E7!F"6     ( ) :;,xx13   -  D"# $ % & '*+ 2345 89B !.<*GHC 10A=>?@ / F GRPH,0G   HASH      J7l RULR$@^& $B@ @    $ $$Hl D h  $Hl D h$Hl@f$>+~@f@f @Z7HASH52 (" " &.@  k/&,'0Q(v)*+0 3,Qh-v /Ty,Qv ! " /# T$ y% 0  h4@@BB ,Bh1H 6H0LKUP  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"$NAMEDefault Default SSHeaderBodyFooterFootnoteFootnote Index Bullet Title Section 1 Q & AQQA DefinitionCode ChecklistNumberClassic" Blue Gray 10 Blue Gray 2>ColorfulL 3D Table 1Z 3D Table 2e AccountingnHarvard{LegalDiamondEmphasisFilename CodeLinesWarning Doc ReferenceSubtitle Section 2DFNTM HelveticaGenevaGenevaTimesPalatinoCourierMCROMCROoBlNoBlNBBARBBARMARKMRKS MOBJWMBTETBLXDSUMhHDNIhSTYLiMCROpoBlNBBARMARKWMBTETBL