Guest User

Untitled

a guest
May 25th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.69 KB | None | 0 0
  1. import objc
  2. from ctypes import create_string_buffer, c_void_p, cast
  3. from Foundation import NSBundle
  4.  
  5. Security = NSBundle.bundleWithIdentifier_('com.apple.security')
  6.  
  7. # CMSDecoder.h
  8. kCMSSignerUnsigned = 0
  9. kCMSSignerValid = 1
  10. kCMSSignerNeedsDetachedContent = 2
  11. kCMSSignerInvalidSignature = 3
  12. kCMSSignerInvalidCert = 4
  13. kCMSSignerInvalidIndex = 5
  14.  
  15. # cssmerr.h - you don't need all of these, only the ones you want to check for
  16. CSSMERR_TP_AUTHENTICATION_FAILED = -2147409657
  17. CSSMERR_TP_CERTGROUP_INCOMPLETE = -2147409656
  18. CSSMERR_TP_CERTIFICATE_CANT_OPERATE = -2147409655
  19. CSSMERR_TP_CERT_EXPIRED = -2147409654
  20. CSSMERR_TP_CERT_NOT_VALID_YET = -2147409653
  21. CSSMERR_TP_CERT_REVOKED = -2147409652
  22. CSSMERR_TP_CERT_SUSPENDED = -2147409651
  23. CSSMERR_TP_CRL_ALREADY_SIGNED = -2147409849
  24. CSSMERR_TP_DEVICE_FAILED = -2147409691
  25. CSSMERR_TP_DEVICE_RESET = -2147409692
  26. CSSMERR_TP_FUNCTION_FAILED = -2147409910
  27. CSSMERR_TP_FUNCTION_NOT_IMPLEMENTED = -2147409913
  28. CSSMERR_TP_INSUFFICIENT_CLIENT_IDENTIFICATION = -2147409693
  29. CSSMERR_TP_INSUFFICIENT_CREDENTIALS = -2147409650
  30. CSSMERR_TP_INTERNAL_ERROR = -2147409919
  31. CSSMERR_TP_INVALID_ACTION = -2147409649
  32. CSSMERR_TP_INVALID_ACTION_DATA = -2147409648
  33. CSSMERR_TP_INVALID_ANCHOR_CERT = -2147409646
  34. CSSMERR_TP_INVALID_AUTHORITY = -2147409645
  35. CSSMERR_TP_INVALID_CALLBACK = -2147409625
  36. CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER = -2147409663
  37. CSSMERR_TP_INVALID_CERTGROUP = -2147409660
  38. CSSMERR_TP_INVALID_CERTGROUP_POINTER = -2147409854
  39. CSSMERR_TP_INVALID_CERTIFICATE = -2147409643
  40. CSSMERR_TP_INVALID_CERT_AUTHORITY = -2147409642
  41. CSSMERR_TP_INVALID_CERT_POINTER = -2147409853
  42. CSSMERR_TP_INVALID_CL_HANDLE = -2147409838
  43. CSSMERR_TP_INVALID_CONTEXT_HANDLE = -2147409856
  44. CSSMERR_TP_INVALID_CRL = -2147409638
  45. CSSMERR_TP_INVALID_CRLGROUP = -2147409659
  46. CSSMERR_TP_INVALID_CRLGROUP_POINTER = -2147409658
  47. CSSMERR_TP_INVALID_CRL_AUTHORITY = -2147409641
  48. CSSMERR_TP_INVALID_CRL_ENCODING = -2147409640
  49. CSSMERR_TP_INVALID_CRL_POINTER = -2147409852
  50. CSSMERR_TP_INVALID_CRL_TYPE = -2147409639
  51. CSSMERR_TP_INVALID_CSP_HANDLE = -2147409840
  52. CSSMERR_TP_INVALID_DATA = -2147409850
  53. CSSMERR_TP_INVALID_DB_HANDLE = -2147409846
  54. CSSMERR_TP_INVALID_DB_LIST = -2147409844
  55. CSSMERR_TP_INVALID_DB_LIST_POINTER = -2147409843
  56. CSSMERR_TP_INVALID_DL_HANDLE = -2147409839
  57. CSSMERR_TP_INVALID_FIELD_POINTER = -2147409851
  58. CSSMERR_TP_INVALID_FORM_TYPE = -2147409637
  59. CSSMERR_TP_INVALID_ID = -2147409636
  60. CSSMERR_TP_INVALID_IDENTIFIER = -2147409635
  61. CSSMERR_TP_INVALID_IDENTIFIER_POINTER = -2147409662
  62. CSSMERR_TP_INVALID_INDEX = -2147409634
  63. CSSMERR_TP_INVALID_INPUT_POINTER = -2147409915
  64. CSSMERR_TP_INVALID_KEYCACHE_HANDLE = -2147409661
  65. CSSMERR_TP_INVALID_NAME = -2147409633
  66. CSSMERR_TP_INVALID_NETWORK_ADDR = -2147409833
  67. CSSMERR_TP_INVALID_NUMBER_OF_FIELDS = -2147409848
  68. CSSMERR_TP_INVALID_OUTPUT_POINTER = -2147409914
  69. CSSMERR_TP_INVALID_PASSTHROUGH_ID = -2147409834
  70. CSSMERR_TP_INVALID_POINTER = -2147409916
  71. CSSMERR_TP_INVALID_POLICY_IDENTIFIERS = -2147409632
  72. CSSMERR_TP_INVALID_REASON = -2147409630
  73. CSSMERR_TP_INVALID_REQUEST_INPUTS = -2147409629
  74. CSSMERR_TP_INVALID_RESPONSE_VECTOR = -2147409628
  75. CSSMERR_TP_INVALID_SIGNATURE = -2147409627
  76. CSSMERR_TP_INVALID_STOP_ON_POLICY = -2147409626
  77. CSSMERR_TP_INVALID_TIMESTRING = -2147409631
  78. CSSMERR_TP_INVALID_TUPLE = -2147409624
  79. CSSMERR_TP_INVALID_TUPLEGROUP = -2147409614
  80. CSSMERR_TP_INVALID_TUPLEGROUP_POINTER = -2147409615
  81. CSSMERR_TP_IN_DARK_WAKE = -2147409690
  82. CSSMERR_TP_MDS_ERROR = -2147409917
  83. CSSMERR_TP_MEMORY_ERROR = -2147409918
  84. CSSMERR_TP_NOT_SIGNER = -2147409623
  85. CSSMERR_TP_NOT_TRUSTED = -2147409622
  86. CSSMERR_TP_NO_DEFAULT_AUTHORITY = -2147409621
  87. CSSMERR_TP_NO_USER_INTERACTION = -2147409696
  88. CSSMERR_TP_OS_ACCESS_DENIED = -2147409911
  89. CSSMERR_TP_REJECTED_FORM = -2147409620
  90. CSSMERR_TP_REQUEST_LOST = -2147409619
  91. CSSMERR_TP_REQUEST_REJECTED = -2147409618
  92. CSSMERR_TP_SELF_CHECK_FAILED = -2147409912
  93. CSSMERR_TP_SERVICE_NOT_AVAILABLE = -2147409694
  94. CSSMERR_TP_UNKNOWN_FORMAT = -2147409842
  95. CSSMERR_TP_UNKNOWN_TAG = -2147409841
  96. CSSMERR_TP_UNSUPPORTED_ADDR_TYPE = -2147409617
  97. CSSMERR_TP_UNSUPPORTED_SERVICE = -2147409616
  98. CSSMERR_TP_USER_CANCELED = -2147409695
  99. CSSMERR_TP_VERIFICATION_FAILURE = -2147409847
  100. CSSMERR_TP_VERIFY_ACTION_FAILED = -2147409644
  101.  
  102. _ = [
  103. ('CMSDecoderGetTypeID', 'Q'),
  104. ('SecPolicyGetTypeID', 'Q'),
  105. ('SecTrustGetTypeID', 'Q'),
  106. ]
  107. objc.loadBundleFunctions(Security, globals(), _)
  108.  
  109. CMSDecoderRef = objc.registerCFSignature('CMSDecoderRef', '^{_CMSDecoder=}', CMSDecoderGetTypeID())
  110. SecPolicyRef = objc.registerCFSignature('SecPolicyRef', '^{OpaqueSecPolicyRef=}', SecPolicyGetTypeID())
  111. SecTrustRef = objc.registerCFSignature('SecTrustRef', '^{__SecTrust=}', SecTrustGetTypeID())
  112.  
  113. _ = [
  114. ('CMSDecoderCreate', 'io^^{_CMSDecoder}'),
  115. ('CMSDecoderSetDetachedContent', 'i^{_CMSDecoder=}^{__CFData=}'),
  116. ('CMSDecoderUpdateMessage', 'i^{_CMSDecoder=}^vQ'),
  117. ('CMSDecoderFinalizeMessage', 'i^{_CMSDecoder=}'),
  118. ('CMSDecoderCopySignerStatus', 'i^{_CMSDecoder=}Q@Bo^Io^^{__SecTrust}o^i'),
  119. ('SecPolicyCreateBasicX509', '^{OpaqueSecPolicyRef=}'),
  120. ]
  121. objc.loadBundleFunctions(Security, globals(), _)
  122.  
  123. def check_detached_sig(message_path, signature_path, signer_index=0, trust_policy=None, evaluate=True):
  124. # Read in the message
  125. f = open(message_path, 'rb')
  126. message = f.read()
  127. f.close()
  128. message_bytes = buffer(message)
  129. # Read in the signature
  130. f = open(signature_path, 'rb')
  131. signature = f.read()
  132. f.close()
  133. signature_bytes = cast(create_string_buffer(signature), c_void_p)
  134. result, decoder = CMSDecoderCreate(None)
  135. result = CMSDecoderSetDetachedContent(decoder, message_bytes)
  136. # For some reason CMSDecoderUpdateMessage takes a freaking raw buffer
  137. result = CMSDecoderUpdateMessage(decoder, signature_bytes.value, len(signature))
  138. result = CMSDecoderFinalizeMessage(decoder)
  139. if trust_policy is None:
  140. trust_policy = SecPolicyCreateBasicX509()
  141. # returns: result, signer_status, sec_trust, cert_verify_result
  142. return CMSDecoderCopySignerStatus(decoder, signer_index, trust_policy, evaluate, None, None, None)
  143.  
  144. # Example usage:
  145. result, signer_status, sec_trust, cert_verify_result = check_detached_sig('test.txt', 'test.txt.sig')
  146.  
  147. # In testing, I was able to generate a self-signed cert and create a detached signature:
  148. # openssl smime -sign -signer signer_cert.pem -inkey signer_key.pem -binary -in test.txt -outform der -out test.txt.sig
  149. #
  150. # When tested against check_detached_sig, I received kCMSSignerInvalidCert (4) for signer_status
  151. # which indicates that the message was properly signed, but the signer's cert is unknown regarding trust.
  152. #
  153. # Modifying the test.txt (but re-using the same signature), I received kCMSSignerInvalidSignature (3) as expected.
  154. #
  155. # By importing the signer_cert.pem into the Keychain and then marking it as trusted (since it's self-signed), I was
  156. # able to achieve kCMSSignerValid (1).
Add Comment
Please, Sign In to add comment