2  * Copyright (c) 2000-2004,2011-2012,2014 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  26 // transition - transition layer for CSSM API/SPI calls. 
  28 // This file defines all functions that connect the CSSM API (CSSM_*) 
  29 // to a plugin's SPI (CSSM_SPI_*) functions. The bulk of these functions 
  30 // is automatically generated by the Perl script transition.pl (thanks, Larry!) 
  31 // from the cssm*.h official header files, under control of the configuration 
  32 // file transition.cfg. Those that need special magic are marked "custom" in 
  33 // transition.cfg and are defined here. 
  35 // @@@ Reconsider CSP locking for context operations 
  38 #include "attachfactory.h" 
  40 #include "cssmcontext.h" 
  41 #include <Security/cssmcspi.h> 
  42 #include <Security/cssmdli.h> 
  43 #include <Security/cssmcli.h> 
  44 #include <Security/cssmaci.h> 
  45 #include <Security/cssmtpi.h> 
  46 #include <Security/cssmkrapi.h> 
  47 #include <Security/cssmkrspi.h> 
  48 #include <security_cdsa_utilities/cssmbridge.h> 
  52 // Names for the standard Attachment types 
  54 typedef StandardAttachment
<CSSM_SERVICE_CSP
, CSSM_SPI_CSP_FUNCS
> CSPAttachment
; 
  55 typedef StandardAttachment
<CSSM_SERVICE_DL
, CSSM_SPI_DL_FUNCS
> DLAttachment
; 
  56 typedef StandardAttachment
<CSSM_SERVICE_CL
, CSSM_SPI_CL_FUNCS
> CLAttachment
; 
  57 typedef StandardAttachment
<CSSM_SERVICE_AC
, CSSM_SPI_AC_FUNCS
> ACAttachment
; 
  58 typedef StandardAttachment
<CSSM_SERVICE_TP
, CSSM_SPI_TP_FUNCS
> TPAttachment
; 
  62 // A conditional locking class for always-right(TM) lock management. 
  66         Attachment 
&attachment
; 
  68         TransitLock(Attachment 
&att
) : attachment(att
) 
  70                 attachment
.module.safeLock(); 
  75                 attachment
.module.safeUnlock(); 
  82 // Context management functions 
  85 CSSM_CSP_CreateSignatureContext (CSSM_CSP_HANDLE CSPHandle
, 
  86                                  CSSM_ALGORITHMS AlgorithmID
, 
  87                                  const CSSM_ACCESS_CREDENTIALS 
*AccessCred
, 
  89                                  CSSM_CC_HANDLE 
*NewContextHandle
) 
  92     HandleContext::Maker 
maker(CSPHandle
); 
  93     maker
.setup(AccessCred
); 
  94     maker
.setup(Key
, CSSMERR_CSP_MISSING_ATTR_KEY
); 
  96     maker
.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS
, AccessCred
); 
  97     maker
.put(CSSM_ATTRIBUTE_KEY
, Key
); 
  98     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_SIGNATURE
, AlgorithmID
); 
 104 CSSM_CSP_CreateSymmetricContext (CSSM_CSP_HANDLE CSPHandle
, 
 105                                  CSSM_ALGORITHMS AlgorithmID
, 
 106                                  CSSM_ENCRYPT_MODE Mode
, 
 107                                  const CSSM_ACCESS_CREDENTIALS 
*AccessCred
, 
 109                                  const CSSM_DATA 
*InitVector
, 
 110                                  CSSM_PADDING Padding
, 
 112                                  CSSM_CC_HANDLE 
*NewContextHandle
) 
 115     if (Reserved 
!= NULL
) 
 116         CssmError::throwMe(CSSM_ERRCODE_INVALID_POINTER
); 
 117     HandleContext::Maker 
maker(CSPHandle
); 
 119     maker
.setup(AccessCred
); 
 121     maker
.setup(InitVector
); 
 122     maker
.setup(Padding
); 
 124     maker
.put(CSSM_ATTRIBUTE_MODE
, Mode
); 
 125     maker
.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS
, AccessCred
); 
 126     maker
.put(CSSM_ATTRIBUTE_KEY
, Key
); 
 127     maker
.put(CSSM_ATTRIBUTE_INIT_VECTOR
, InitVector
); 
 128     maker
.put(CSSM_ATTRIBUTE_PADDING
, Padding
); 
 129     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_SYMMETRIC
, AlgorithmID
); 
 135 CSSM_CSP_CreateDigestContext (CSSM_CSP_HANDLE CSPHandle
, 
 136                               CSSM_ALGORITHMS AlgorithmID
, 
 137                               CSSM_CC_HANDLE 
*NewContextHandle
) 
 140     HandleContext::Maker 
maker(CSPHandle
); 
 142     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_DIGEST
, AlgorithmID
); 
 148 CSSM_CSP_CreateMacContext (CSSM_CSP_HANDLE CSPHandle
, 
 149                            CSSM_ALGORITHMS AlgorithmID
, 
 151                            CSSM_CC_HANDLE 
*NewContextHandle
) 
 154     HandleContext::Maker 
maker(CSPHandle
); 
 155     maker
.setup(Key
, CSSMERR_CSP_MISSING_ATTR_KEY
); 
 157     maker
.put(CSSM_ATTRIBUTE_KEY
, Key
); 
 158     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_MAC
, AlgorithmID
); 
 164 CSSM_CSP_CreateRandomGenContext (CSSM_CSP_HANDLE CSPHandle
, 
 165                                  CSSM_ALGORITHMS AlgorithmID
, 
 166                                  const CSSM_CRYPTO_DATA 
*Seed
, 
 168                                  CSSM_CC_HANDLE 
*NewContextHandle
) 
 171     HandleContext::Maker 
maker(CSPHandle
); 
 173     maker
.setup(Length
, CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE
); 
 175     maker
.put(CSSM_ATTRIBUTE_SEED
, Seed
); 
 176     maker
.put(CSSM_ATTRIBUTE_OUTPUT_SIZE
, (uint32_t)Length
); 
 177     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_RANDOMGEN
, AlgorithmID
); 
 183 CSSM_CSP_CreateAsymmetricContext (CSSM_CSP_HANDLE CSPHandle
, 
 184                                   CSSM_ALGORITHMS AlgorithmID
, 
 185                                   const CSSM_ACCESS_CREDENTIALS 
*AccessCred
, 
 187                                   CSSM_PADDING Padding
, 
 188                                   CSSM_CC_HANDLE 
*NewContextHandle
) 
 191     HandleContext::Maker 
maker(CSPHandle
); 
 192     maker
.setup(AccessCred
, CSSMERR_CSP_MISSING_ATTR_ACCESS_CREDENTIALS
); 
 193     maker
.setup(Key
, CSSMERR_CSP_MISSING_ATTR_KEY
); 
 194     maker
.setup(Padding
); 
 196     maker
.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS
, AccessCred
); 
 197     maker
.put(CSSM_ATTRIBUTE_KEY
, Key
); 
 198     maker
.put(CSSM_ATTRIBUTE_PADDING
, Padding
); 
 199     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_ASYMMETRIC
, AlgorithmID
); 
 205 CSSM_CSP_CreateDeriveKeyContext (CSSM_CSP_HANDLE CSPHandle
, 
 206                                  CSSM_ALGORITHMS AlgorithmID
, 
 207                                  CSSM_KEY_TYPE DeriveKeyType
, 
 208                                  uint32 DeriveKeyLengthInBits
, 
 209                                  const CSSM_ACCESS_CREDENTIALS 
*AccessCred
, 
 210                                  const CSSM_KEY 
*BaseKey
, 
 211                                  uint32 IterationCount
, 
 212                                  const CSSM_DATA 
*Salt
, 
 213                                  const CSSM_CRYPTO_DATA 
*Seed
, 
 214                                  CSSM_CC_HANDLE 
*NewContextHandle
) 
 217     HandleContext::Maker 
maker(CSPHandle
); 
 218     maker
.setup(DeriveKeyType
, CSSMERR_CSP_INVALID_ATTR_KEY_TYPE
); 
 219     maker
.setup(DeriveKeyLengthInBits
, CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH
); 
 220     maker
.setup(AccessCred
); 
 221     maker
.setup(BaseKey
); 
 222     maker
.setup(IterationCount
); 
 226     maker
.put(CSSM_ATTRIBUTE_KEY_TYPE
, DeriveKeyType
); 
 227     maker
.put(CSSM_ATTRIBUTE_KEY_LENGTH
, DeriveKeyLengthInBits
); 
 228     maker
.put(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS
, AccessCred
); 
 229     maker
.put(CSSM_ATTRIBUTE_KEY
, BaseKey
); 
 230     maker
.put(CSSM_ATTRIBUTE_ITERATION_COUNT
, IterationCount
); 
 231     maker
.put(CSSM_ATTRIBUTE_SALT
, Salt
); 
 232     maker
.put(CSSM_ATTRIBUTE_SEED
, Seed
); 
 233     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_DERIVEKEY
, AlgorithmID
); 
 239 CSSM_CSP_CreateKeyGenContext (CSSM_CSP_HANDLE CSPHandle
, 
 240                               CSSM_ALGORITHMS AlgorithmID
, 
 241                               uint32 KeySizeInBits
, 
 242                               const CSSM_CRYPTO_DATA 
*Seed
, 
 243                               const CSSM_DATA 
*Salt
, 
 244                               const CSSM_DATE 
*StartDate
, 
 245                               const CSSM_DATE 
*EndDate
, 
 246                               const CSSM_DATA 
*Params
, 
 247                               CSSM_CC_HANDLE 
*NewContextHandle
) 
 250     HandleContext::Maker 
maker(CSPHandle
); 
 251     maker
.setup(KeySizeInBits
, CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH
); 
 254     maker
.setup(StartDate
); 
 255     maker
.setup(EndDate
); 
 258     maker
.put(CSSM_ATTRIBUTE_KEY_LENGTH
, KeySizeInBits
); 
 259     maker
.put(CSSM_ATTRIBUTE_SEED
, Seed
); 
 260     maker
.put(CSSM_ATTRIBUTE_SALT
, Salt
); 
 261     maker
.put(CSSM_ATTRIBUTE_START_DATE
, StartDate
); 
 262     maker
.put(CSSM_ATTRIBUTE_END_DATE
, EndDate
); 
 263     maker
.put(CSSM_ATTRIBUTE_ALG_PARAMS
, Params
); 
 264     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_KEYGEN
, AlgorithmID
); 
 270 CSSM_CSP_CreatePassThroughContext (CSSM_CSP_HANDLE CSPHandle
, 
 272                                    CSSM_CC_HANDLE 
*NewContextHandle
) 
 275     HandleContext::Maker 
maker(CSPHandle
); 
 276     maker
.setup(Key
, CSSMERR_CSP_MISSING_ATTR_KEY
); 
 278     maker
.put(CSSM_ATTRIBUTE_KEY
, Key
); 
 279     Required(NewContextHandle
) = maker(CSSM_ALGCLASS_NONE
, CSSM_ALGID_NONE
); 
 285 // CSSM_GetContext makes a deep copy of a CSP context and hands it to the 
 286 // caller. The result is NOT a HandleContext, but a bare Context that is 
 287 // in no dictionaries etc. User must delete it by calling CSSM_FreeContext. 
 290 CSSM_GetContext (CSSM_CC_HANDLE CCHandle
, 
 291                  CSSM_CONTEXT_PTR 
*ContextP
) 
 294     HandleContext 
&context 
= HandleObject::find
<HandleContext
>((CSSM_HANDLE
)CCHandle
, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE
); 
 295     Context 
*newContext 
= new(context
.attachment
) Context(context
.type(), context
.algorithm()); 
 297         newContext
->CSPHandle 
= context
.attachment
.handle(); 
 298         newContext
->copyFrom(context
, context
.attachment
); 
 299         Required(ContextP
) = newContext
; 
 301         context
.attachment
.free(newContext
); 
 309 // Since we allocated all the data in one fell heap, our FreeContext 
 310 // function is disappointingly simple. 
 313 CSSM_FreeContext (CSSM_CONTEXT_PTR ContextP
) 
 316     Context 
*context 
= &Context::required(ContextP
); 
 317     context
->destroy(context
, HandleObject::find
<CSPAttachment
>(context
->CSPHandle
, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE
)); 
 323 CSSM_SetContext (CSSM_CC_HANDLE CCHandle
, 
 324                  const CSSM_CONTEXT 
*ContextP
) 
 327     const Context 
&source 
= Context::required(ContextP
); 
 328     HandleContext 
&context 
= HandleObject::find
<HandleContext
>((CSSM_HANDLE
)CCHandle
, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE
); 
 330     CSSM_CONTEXT_ATTRIBUTE 
*oldAttributes 
= context
.ContextAttributes
; 
 331     uint32 oldCount 
= context
.NumberOfAttributes
; 
 332         CSSM_CONTEXT_TYPE oldType 
= context
.ContextType
; 
 333     CSSM_ALGORITHMS oldAlgorithm 
= context
.AlgorithmType
; 
 335     context
.copyFrom(source
, context
.attachment
); 
 336         context
.ContextType 
= source
.ContextType
; 
 337     context
.AlgorithmType 
= source
.AlgorithmType
; 
 339     if (CSSM_RETURN err 
= context
.validateChange(CSSM_CONTEXT_EVENT_UPDATE
)) { 
 340                 context
.attachment
.free(context
.ContextAttributes
);     // free rejected attribute blob 
 341         context
.ContextAttributes 
= oldAttributes
;      // restore... 
 342         context
.NumberOfAttributes 
= oldCount
;          // ... old 
 343                 context
.ContextType 
= oldType
;                          //  ... values 
 344         context
.AlgorithmType 
= oldAlgorithm
;           //   ... in context 
 345         CssmError::throwMe(err
);                                                // tell the caller it failed 
 348     context
.attachment
.free(oldAttributes
); 
 354 CSSM_DeleteContext (CSSM_CC_HANDLE CCHandle
) 
 357     HandleContext 
&context 
= enterContext(CCHandle
); 
 358         StLock
<CountingMutex
, &CountingMutex::enter
, &CountingMutex::exit
>  
 359                 _(context
.attachment
, true); 
 361     // ignore error return from CSP event notify (can't decline deletion) 
 362     context
.validateChange(CSSM_CONTEXT_EVENT_DELETE
); 
 364     context
.destroy(&context
, context
.attachment
); 
 370 // The GetContextAttribute API is fatally flawed. The standard implies a deep 
 371 // copy of the attribute value, but no release function exists. Instead, we 
 372 // return a shallow copy (sharing structure) which you need not release, but 
 373 // which becomes invalid when the source Context is destroyed. 
 376 CSSM_GetContextAttribute (const CSSM_CONTEXT 
*Context
, 
 377                           uint32 AttributeType
, 
 378                           CSSM_CONTEXT_ATTRIBUTE_PTR 
*ContextAttribute
) 
 381     CSSM_ATTRIBUTE_TYPE type 
= CSSM_ATTRIBUTE_TYPE(AttributeType
);      // CDSA defect 
 382     Required(ContextAttribute
) = Context::required(Context
).find(type
); 
 388 CSSM_UpdateContextAttributes (CSSM_CC_HANDLE CCHandle
, 
 389                               uint32 NumberAttributes
, 
 390                               const CSSM_CONTEXT_ATTRIBUTE 
*ContextAttributes
) 
 393     HandleContext 
&context 
= HandleObject::find
<HandleContext
>((CSSM_HANDLE
)CCHandle
, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE
); 
 394     context
.mergeAttributes(ContextAttributes
, NumberAttributes
); 
 400 CSSM_DeleteContextAttributes (CSSM_CC_HANDLE CCHandle
, 
 401                               uint32 NumberOfAttributes
, 
 402                               const CSSM_CONTEXT_ATTRIBUTE 
*ContextAttributes
) 
 405     if (NumberOfAttributes 
== 0) 
 406         return CSSM_OK
; // I suppose 
 407     Required(ContextAttributes
); // preflight 
 408     HandleContext 
&context 
= HandleObject::find
<HandleContext
>((CSSM_HANDLE
)CCHandle
, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE
); 
 409     for (uint32 n 
= 0; n 
< NumberOfAttributes
; n
++) 
 410         context
.deleteAttribute(ContextAttributes
[n
].AttributeType
); 
 416 // Miscellaneous odds and ends - these functions just need a wee bit of 
 417 // manual massaging to fit. 
 420 CSSM_DigestDataClone (CSSM_CC_HANDLE ccHandle
, 
 421                       CSSM_CC_HANDLE 
*newCCHandle
) 
 424     HandleContext 
&context 
= HandleObject::findAndLock
<HandleContext
>((CSSM_HANDLE
)ccHandle
, CSSM_ERRCODE_INVALID_CONTEXT_HANDLE
); 
 425         TransitLock 
_(context
.attachment
); 
 426     HandleContext 
*newContext 
= 
 427         new(context
.attachment
) HandleContext(context
.attachment
, context
.type(), context
.algorithm()); 
 429         newContext
->CSPHandle 
= context
.attachment
.handle(); 
 430         newContext
->copyFrom(context
, context
.attachment
); 
 431                 context
.attachment
.downcalls
.DigestDataClone(context
.attachment
.handle(), ccHandle
, newContext
->handle()); 
 432         Required(newCCHandle
) = newContext
->handle(); 
 434         newContext
->destroy(newContext
, context
.attachment
); 
 442 CSSM_QueryKeySizeInBits (CSSM_CSP_HANDLE CSPHandle
, 
 443                          CSSM_CC_HANDLE ccHandle
, 
 445                          CSSM_KEY_SIZE_PTR keySize
) 
 447         //@@@ could afford not to lock attachment in have-CC case 
 451         CSPAttachment 
*attachment
; 
 452         if (ccHandle 
== (CSSM_CC_HANDLE
) HandleObject::invalidHandle
) { 
 453                 // key specified by CSPHandle and Key 
 454                 attachment 
= &enterAttachment
<CSPAttachment
>(CSPHandle
); 
 457                 // key specified by ccHandle 
 458                 HandleContext 
*ctx 
= &enterContext(ccHandle
); 
 460                         attachment 
= &ctx
->attachment
; 
 462                         CSPHandle 
= context
->CSPHandle
; 
 463                         key 
= &context
->get
<CssmKey
>(CSSM_ATTRIBUTE_KEY
, 
 464                                                                                  CSSMERR_CSP_INVALID_KEY
); 
 470         TransitLock 
_(*attachment
); 
 471         CSSM_RETURN result 
= attachment
->downcalls
.QueryKeySizeInBits(CSPHandle
, 
 472                         ccHandle
, context
, key
, keySize
); 
 479 CSSM_GenerateAlgorithmParams (CSSM_CC_HANDLE CCHandle
, 
 484     // this function has more subtle locking than usual. Pay attention: 
 486     // (1) Resolve context and ensure attachment exit 
 487         HandleContext 
&context 
= enterContext(CCHandle
); 
 488     StLock
<CountingMutex
, &CountingMutex::enter
, &CountingMutex::exit
> _(context
.attachment
, true); 
 490     // (2) Call CSP, acquiring module safe-lock for a moment (only) 
 491         CSSM_CONTEXT_ATTRIBUTE_PTR attributes
; 
 494         StLock
<Module
, &Module::safeLock
, &Module::safeUnlock
> _(context
.attachment
.module); 
 495         if (CSSM_RETURN err 
= 
 496                 context
.attachment
.downcalls
.GenerateAlgorithmParams(context
.attachment
.handle(), 
 499                 &count
, &attributes
)) 
 500             CssmError::throwMe(err
); 
 503     // (3) Merge the attributes returned into the context, which will (again) acquire the module safe-lock internally 
 505             context
.mergeAttributes(attributes
, count
); 
 506     // the memory at (attributes, count) belongs to the CSP; don't free it here 
 512 // Include the auto-generated functions 
 514 #include <derived_src/transition.gen>