MYPublicKey.m
author Jens Alfke <jens@mooseyard.com>
Thu Jun 04 18:36:30 2009 -0700 (2009-06-04)
changeset 19 f6c91b9da05b
parent 14 3af1d1c0ceb5
child 21 2c300b15b381
permissions -rw-r--r--
Whew! MYParsedCertificate can now generate certs from scratch. Also added improvements and fixes to the BER/DER codecs.
snej@0
     1
//
snej@0
     2
//  MYPublicKey.m
snej@0
     3
//  MYCrypto
snej@0
     4
//
snej@0
     5
//  Created by Jens Alfke on 3/21/09.
snej@0
     6
//  Copyright 2009 Jens Alfke. All rights reserved.
snej@0
     7
//
snej@0
     8
snej@0
     9
#import "MYPublicKey.h"
snej@0
    10
#import "MYCrypto_Private.h"
snej@0
    11
#import "MYDigest.h"
snej@0
    12
#import "MYErrorUtils.h"
snej@0
    13
#import <CommonCrypto/CommonDigest.h>
snej@0
    14
snej@0
    15
snej@0
    16
#pragma mark -
snej@0
    17
@implementation MYPublicKey
snej@0
    18
snej@0
    19
snej@0
    20
- (void) dealloc
snej@0
    21
{
snej@0
    22
    [_digest release];
snej@0
    23
    [super dealloc];
snej@0
    24
}
snej@0
    25
snej@0
    26
- (SecExternalItemType) keyType {
snej@3
    27
#if MYCRYPTO_USE_IPHONE_API
snej@3
    28
    return kSecAttrKeyClassPublic;
snej@3
    29
#else
snej@0
    30
    return kSecItemTypePublicKey;
snej@3
    31
#endif
snej@0
    32
}
snej@3
    33
snej@0
    34
- (NSUInteger)hash {
snej@0
    35
    return self.publicKeyDigest.hash;
snej@0
    36
}
snej@0
    37
snej@0
    38
- (NSString*) description {
snej@0
    39
    return $sprintf(@"%@[%@]", [self class], self.publicKeyDigest.abbreviatedHexString);
snej@0
    40
}
snej@0
    41
snej@0
    42
- (MYSHA1Digest*) publicKeyDigest {
snej@0
    43
    if (!_digest)
snej@3
    44
        _digest = [[self _keyDigest] retain];
snej@0
    45
    return _digest;
snej@0
    46
}
snej@0
    47
snej@3
    48
#if !MYCRYPTO_USE_IPHONE_API
snej@13
    49
- (SecExternalFormat) _externalFormat {
snej@14
    50
    return kSecFormatBSAFE;
snej@0
    51
}
snej@3
    52
#endif
snej@0
    53
snej@0
    54
snej@13
    55
- (NSData*) rawEncryptData: (NSData*)data {
snej@3
    56
    return [self _crypt: data operation: YES];
snej@0
    57
}
snej@0
    58
snej@0
    59
snej@0
    60
- (BOOL) verifySignature: (NSData*)signature ofData: (NSData*)data {
snej@0
    61
    Assert(data);
snej@0
    62
    Assert(signature);
snej@1
    63
    
snej@3
    64
#if MYCRYPTO_USE_IPHONE_API
snej@3
    65
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
snej@3
    66
    CC_SHA1(data.bytes,data.length, digest);
snej@3
    67
    OSStatus err = SecKeyRawVerify(self.keyRef, kSecPaddingPKCS1SHA1,
snej@3
    68
                                   digest,sizeof(digest), //data.bytes, data.length,
snej@3
    69
                                   signature.bytes, signature.length);
snej@3
    70
    return err==noErr;
snej@3
    71
    
snej@3
    72
#else
jens@17
    73
    CSSM_CC_HANDLE ccHandle = [self _createSignatureContext: CSSM_ALGID_SHA1WithRSA];
snej@0
    74
    if (!ccHandle) return NO;
snej@0
    75
    CSSM_DATA original = {data.length, (void*)data.bytes};
snej@0
    76
    CSSM_DATA sig = {signature.length, (void*)signature.bytes};
snej@0
    77
    CSSM_RETURN cssmErr = CSSM_VerifyData(ccHandle, &original, 1, CSSM_ALGID_NONE, &sig);
snej@0
    78
    CSSM_DeleteContext(ccHandle);
snej@0
    79
    if (cssmErr == CSSM_OK)
snej@0
    80
        return YES;
snej@0
    81
    if (cssmErr != CSSMERR_CSP_VERIFY_FAILED)
snej@0
    82
        Warn(@"CSSM error verifying signature: %u", MYErrorName(MYCSSMErrorDomain,cssmErr));
snej@0
    83
    return NO;
snej@3
    84
#endif
snej@0
    85
}
snej@0
    86
snej@0
    87
snej@4
    88
#if !TARGET_OS_IPHONE
snej@4
    89
- (CSSM_WRAP_KEY*) _unwrappedCSSMKey {
snej@4
    90
    const CSSM_KEY *key = self.cssmKey;
snej@4
    91
    
snej@4
    92
    if (key->KeyHeader.BlobType == CSSM_KEYBLOB_WRAPPED) {
snej@4
    93
        Warn(@"Key is already wrapped.\n");
snej@4
    94
        return NULL;
snej@4
    95
    }
snej@4
    96
    
snej@4
    97
    if (key->KeyHeader.KeyClass != CSSM_KEYCLASS_PUBLIC_KEY)
snej@4
    98
        Warn(@"Warning: Null wrapping a non-public key - this is a dangerous operation.\n");
snej@4
    99
    
snej@4
   100
    const CSSM_ACCESS_CREDENTIALS* credentials;
snej@4
   101
    credentials = [self cssmCredentialsForOperation: CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED
snej@4
   102
                                               type: kSecCredentialTypeDefault error: nil];
snej@4
   103
    CSSM_CC_HANDLE ccHandle;
snej@4
   104
    if (!checkcssm(CSSM_CSP_CreateSymmetricContext(self.cssmCSPHandle, 
snej@4
   105
                                                   CSSM_ALGID_NONE, CSSM_ALGMODE_WRAP, 
snej@4
   106
                                                   NULL, NULL, NULL, 
snej@4
   107
                                                   CSSM_PADDING_NONE, NULL, 
snej@4
   108
                                                   &ccHandle),
snej@4
   109
                   @"CSSM_CSP_CreateSymmetricContext"))
snej@4
   110
        return NULL;
snej@4
   111
                   
snej@4
   112
    CSSM_WRAP_KEY *result = malloc(sizeof(CSSM_WRAP_KEY));
snej@4
   113
    if (!checkcssm(CSSM_WrapKey(ccHandle, credentials, key, NULL, result),
snej@4
   114
                      @"CSSM_WrapKey")) {
snej@4
   115
        free(result);
snej@4
   116
        result = NULL;
snej@4
   117
    }
snej@4
   118
    CSSM_DeleteContext(ccHandle);
snej@4
   119
    return result;
snej@4
   120
}
snej@13
   121
snej@13
   122
snej@13
   123
- (NSData*) wrapSessionKey: (MYSymmetricKey*)sessionKey {
snej@13
   124
    const CSSM_ACCESS_CREDENTIALS* credentials;
snej@13
   125
    credentials = [self cssmCredentialsForOperation: CSSM_ACL_AUTHORIZATION_EXPORT_WRAPPED
snej@13
   126
                                               type: kSecCredentialTypeDefault error: nil];
snej@13
   127
    CSSM_CSP_HANDLE cspHandle = self.cssmCSPHandle;
snej@13
   128
    CSSM_CC_HANDLE ctx;
snej@13
   129
    if (!checkcssm(CSSM_CSP_CreateAsymmetricContext(cspHandle,
snej@13
   130
                                                    self.cssmAlgorithm,
snej@13
   131
                                                    credentials, 
snej@13
   132
                                                    self.cssmKey,
snej@13
   133
                                                    CSSM_PADDING_PKCS1,
snej@13
   134
                                                    &ctx), 
snej@13
   135
                   @"CSSM_CSP_CreateAsymmetricContext"))
snej@13
   136
        return nil;
snej@14
   137
        
snej@13
   138
    // Now wrap the key:
snej@13
   139
    NSData *result = nil;
snej@13
   140
    CSSM_WRAP_KEY wrappedKey = {};
snej@14
   141
    CSSM_DATA descriptiveData = {};
snej@14
   142
    if (checkcssm(CSSM_WrapKey(ctx, credentials, sessionKey.cssmKey, &descriptiveData, &wrappedKey),
snej@13
   143
                  @"CSSM_WrapKey")) {
snej@13
   144
        // ...and copy the wrapped key data to the result NSData:
snej@13
   145
        result = [NSData dataWithBytes: wrappedKey.KeyData.Data length: wrappedKey.KeyData.Length];
snej@13
   146
        CSSM_FreeKey(cspHandle, credentials, &wrappedKey, NO);
snej@13
   147
    }
snej@13
   148
    // Finally, delete the context
snej@13
   149
    CSSM_DeleteContext(ctx);
snej@13
   150
    return result;
snej@13
   151
}
snej@13
   152
snej@13
   153
snej@4
   154
#endif
snej@4
   155
snej@4
   156
snej@0
   157
@end
snej@0
   158
snej@0
   159
snej@0
   160
snej@0
   161
/*
snej@0
   162
 Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
snej@0
   163
 
snej@0
   164
 Redistribution and use in source and binary forms, with or without modification, are permitted
snej@0
   165
 provided that the following conditions are met:
snej@0
   166
 
snej@0
   167
 * Redistributions of source code must retain the above copyright notice, this list of conditions
snej@0
   168
 and the following disclaimer.
snej@0
   169
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
snej@0
   170
 and the following disclaimer in the documentation and/or other materials provided with the
snej@0
   171
 distribution.
snej@0
   172
 
snej@0
   173
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
snej@0
   174
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
snej@0
   175
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
snej@0
   176
 BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
snej@0
   177
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
snej@0
   178
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
snej@0
   179
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
snej@0
   180
 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
snej@0
   181
 */