pal-sgx-get-token 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #!/usr/bin/env python
  2. import os
  3. import sys
  4. import struct
  5. import socket
  6. from google.protobuf import message as _message
  7. from Crypto.PublicKey import RSA
  8. import aesm_pb2
  9. """ Utilities """
  10. def int_to_bytes(i):
  11. b = ""
  12. l = 0
  13. while i > 0:
  14. b = b + chr(i % 256)
  15. i = i // 256
  16. l = l + 1
  17. return b
  18. def bytes_to_int(b):
  19. i = 0
  20. for c in b:
  21. i = i * 256 + ord(c)
  22. return i
  23. """ Reading Sigstruct """
  24. def read_sigstruct(sig):
  25. # field format: (offset, type, value)
  26. fields = dict()
  27. fields['date'] = ( 20, "<HBB", 'year', 'month', 'day')
  28. fields['modulus'] = ( 128, "384s", 'modulus')
  29. fields['exponent'] = ( 512, "<L", 'exponent')
  30. fields['signature'] = ( 516, "384s", 'signature')
  31. fields['miscs'] = ( 900, "4s", 'miscs')
  32. fields['miscmask'] = ( 904, "4s", 'miscmask')
  33. fields['attrs'] = ( 928, "8s8s", 'flags', 'xfrms')
  34. fields['attrmask'] = ( 944, "8s8s", 'flagmask', 'xfrmmask')
  35. fields['mrencalve'] = ( 960, "32s", 'mrenclave')
  36. fields['isvprodid'] = (1024, "<H", 'isvprodid')
  37. fields['isvsvn'] = (1026, "<H", 'isvsvn')
  38. attr = dict()
  39. for key, field in fields.items():
  40. values = struct.unpack_from(field[1], sig, field[0])
  41. for i in range(len(values)):
  42. attr[field[i + 2]] = values[i]
  43. return attr
  44. """ Connect with AESMD """
  45. def connect_aesmd(attr):
  46. req_msg = aesm_pb2.GetTokenReq()
  47. req_msg.req.signature = attr['mrenclave']
  48. req_msg.req.key = attr['modulus']
  49. req_msg.req.attributes = attr['flags'] + attr['xfrms']
  50. req_msg.req.timeout = 10000
  51. req_msg_raw = req_msg.SerializeToString()
  52. aesm_service = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  53. aesm_service.connect("\0sgx_aesm_socket_base" + "\0" * 87)
  54. aesm_service.send(struct.pack("<I", len(req_msg_raw)))
  55. aesm_service.send(req_msg_raw)
  56. ret_msg_size = struct.unpack("<I", aesm_service.recv(4))[0]
  57. ret_msg = aesm_pb2.GetTokenRet()
  58. ret_msg_raw = aesm_service.recv(ret_msg_size)
  59. ret_msg.ParseFromString(ret_msg_raw)
  60. if ret_msg.ret.error != 0:
  61. raise Exception("Failed. (Error Code = %d)" % (ret_msg.ret.error))
  62. return ret_msg.ret.token
  63. """ Main Program """
  64. options = {
  65. # Option name : (Required Value)
  66. 'output': (True, 'output'),
  67. 'sig': (True, 'sigstruct file'),
  68. }
  69. def usage():
  70. usage_message = 'USAGE: ' + sys.argv[0] + ' -help|-h'
  71. for opt, optval in options.items():
  72. if not optval[0]:
  73. usage_message += '['
  74. usage_message += '|-' + opt
  75. if optval[1]:
  76. usage_message += ' <' + optval[1] + '>'
  77. if not optval[0]:
  78. usage_message += ']'
  79. print >> sys.stderr, usage_message
  80. os._exit(-1)
  81. def parse_args():
  82. args = dict()
  83. for opt, optval in options.items():
  84. if optval[1] is None:
  85. args[opt] = False
  86. i = 1
  87. while i < len(sys.argv):
  88. got = sys.argv[i]
  89. if got == '-help' or got == '-h':
  90. usage()
  91. invalid = True
  92. for opt, optval in options.items():
  93. if got != '-' + opt:
  94. continue
  95. if optval[1] is not None:
  96. i += 1
  97. if i == len(sys.argv):
  98. print >>sys.stderr, "Option %s needs a value." % (opt)
  99. usage()
  100. args[opt] = sys.argv[i]
  101. else:
  102. args[opt] = True
  103. invalid = False
  104. break
  105. if invalid:
  106. print >>sys.stderr, "Unknown option: %s." % (got[1:])
  107. usage()
  108. i += 1
  109. for opt, optval in options.items():
  110. if optval[0] and opt not in args:
  111. print >>sys.stderr, "Must specify %s <%s>." % (opt, optval[1])
  112. usage()
  113. return args
  114. if __name__ == "__main__":
  115. # Parse arguments
  116. args = parse_args()
  117. attr = read_sigstruct(open(args['sig'], 'rb').read())
  118. print >>sys.stderr, "Attributes:"
  119. print >>sys.stderr, " mrenclave: %s" % (attr['mrenclave'].encode('hex'))
  120. print >>sys.stderr, " isvprodid: %d" % (attr['isvprodid'])
  121. print >>sys.stderr, " isvsvn: %d" % (attr['isvsvn'])
  122. print >>sys.stderr, " flags: %016x" % (bytes_to_int(attr['flags']))
  123. print >>sys.stderr, " xfrms: %016x" % (bytes_to_int(attr['xfrms']))
  124. print >>sys.stderr, " miscs: %08x" % (bytes_to_int(attr['miscs']))
  125. print >>sys.stderr, " modulus: %s..." % (attr['modulus'].encode('hex')[:32])
  126. print >>sys.stderr, " exponent: %d" % (attr['exponent'])
  127. print >>sys.stderr, " signature: %s..." % (attr['signature'].encode('hex')[:32])
  128. token = connect_aesmd(attr)
  129. open(args['output'], 'wb').write(token)