PageRenderTime 24ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/core/autoinstaller/UpdateEngineExtensions/PlistSigner.m

http://macfuse.googlecode.com/
Objective C | 130 lines | 79 code | 35 blank | 16 comment | 9 complexity | 3c417820f699ddc73353b1fc2318cb25 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0
  1. //
  2. // SignedPlist.m
  3. // autoinstaller
  4. //
  5. // Created by Greg Miller on 7/18/08.
  6. // Copyright 2008 Google Inc. All rights reserved.
  7. //
  8. #import "PlistSigner.h"
  9. #import "Signer.h"
  10. static NSString *const kSignatureKey = @"Signature";
  11. @interface PlistSigner (PrivateMethods)
  12. - (void)setPlist:(NSDictionary *)plist;
  13. // Returns an opaque blob of data generated from |plist|. This blob of data can
  14. // be used for signing and signature verification. However, it should NOT be
  15. // interpreted in any way.
  16. - (NSData *)blobFromDictionary:(NSDictionary *)plist;
  17. @end
  18. @implementation PlistSigner
  19. - (id)init {
  20. return [self initWithSigner:nil plist:nil];
  21. }
  22. - (id)initWithSigner:(Signer *)signer plist:(NSDictionary *)plist {
  23. if ((self = [super init])) {
  24. signer_ = [signer retain];
  25. [self setPlist:plist];
  26. if (signer_ == nil || plist_ == nil) {
  27. [self release];
  28. return nil;
  29. }
  30. }
  31. return self;
  32. }
  33. - (void)dealloc {
  34. [signer_ release];
  35. [plist_ release];
  36. [super dealloc];
  37. }
  38. - (NSDictionary *)plist {
  39. return [[plist_ copy] autorelease];
  40. }
  41. - (BOOL)isPlistSigned {
  42. NSMutableDictionary *mutablePlist = [[plist_ mutableCopy] autorelease];
  43. NSData *signature = [mutablePlist objectForKey:kSignatureKey];
  44. [mutablePlist removeObjectForKey:kSignatureKey];
  45. NSData *blob = [self blobFromDictionary:mutablePlist];
  46. return [signer_ isSignature:signature validForData:blob];
  47. }
  48. - (BOOL)signPlist {
  49. if ([self isPlistSigned]) return YES;
  50. NSMutableDictionary *mutablePlist = [[plist_ mutableCopy] autorelease];
  51. [mutablePlist removeObjectForKey:kSignatureKey];
  52. NSData *blob = [self blobFromDictionary:mutablePlist];
  53. NSData *signature = [signer_ signData:blob];
  54. BOOL ok = NO;
  55. if (signature != nil) {
  56. [mutablePlist setObject:signature forKey:kSignatureKey];
  57. [self setPlist:mutablePlist];
  58. ok = YES;
  59. }
  60. return ok;
  61. }
  62. - (BOOL)unsignedPlist {
  63. if (![self isPlistSigned]) return YES;
  64. NSMutableDictionary *mutablePlist = [[plist_ mutableCopy] autorelease];
  65. [mutablePlist removeObjectForKey:kSignatureKey];
  66. [self setPlist:mutablePlist];
  67. return YES;
  68. }
  69. @end
  70. @implementation PlistSigner (PrivateMethods)
  71. - (void)setPlist:(NSDictionary *)plist {
  72. [plist_ autorelease];
  73. plist_ = [plist copy];
  74. }
  75. - (NSData *)blobFromDictionary:(NSDictionary *)plist {
  76. // In order to sign/very plists on both Tiger and Leoaprd, we need to
  77. // serialize the plist into an NSData, but this will contain an XML comment
  78. // of either "Apple" or "Apple Computer" (Tiger), which will screw up
  79. // signatures. So, we need to convert this XML to a big string, strip off
  80. // the first two lines (which are comments), then return the remainder of the
  81. // XML as a big data blob.
  82. NSData *plistData = [NSPropertyListSerialization
  83. dataFromPropertyList:plist
  84. format:NSPropertyListXMLFormat_v1_0
  85. errorDescription:NULL];
  86. NSString *plistString = [[[NSString alloc]
  87. initWithData:plistData
  88. encoding:NSUTF8StringEncoding] autorelease];
  89. NSArray *lines = [plistString componentsSeparatedByString:@"\n"];
  90. NSRange range = NSMakeRange(2, [lines count] - 2);
  91. NSArray *trimmedLines = [lines subarrayWithRange:range];
  92. NSString *trimmedString = [trimmedLines componentsJoinedByString:@"\n"];
  93. return [trimmedString dataUsingEncoding:NSUTF8StringEncoding];
  94. }
  95. @end