swupdate-common.bbclass 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. def swupdate_is_hash_needed(s, filename):
  2. with open(os.path.join(s, "sw-description"), 'r') as f:
  3. for line in f:
  4. if line.find("@%s" % (filename)) != -1:
  5. return True
  6. return False
  7. def swupdate_get_sha256(s, filename):
  8. import hashlib
  9. m = hashlib.sha256()
  10. with open(os.path.join(s, filename), 'rb') as f:
  11. while True:
  12. data = f.read(1024)
  13. if not data:
  14. break
  15. m.update(data)
  16. return m.hexdigest()
  17. def swupdate_write_sha256(s, filename, hash):
  18. write_lines = []
  19. with open(os.path.join(s, "sw-description"), 'r') as f:
  20. for line in f:
  21. write_lines.append(line.replace("@%s" % (filename), hash))
  22. with open(os.path.join(s, "sw-description"), 'w+') as f:
  23. for line in write_lines:
  24. f.write(line)
  25. def swupdate_expand_bitbake_variables(d, s):
  26. write_lines = []
  27. with open(os.path.join(s, "sw-description"), 'r') as f:
  28. import re
  29. for line in f:
  30. found = False
  31. while True:
  32. m = re.match(r"^(?P<before_placeholder>.+)@@(?P<bitbake_variable_name>\w+)@@(?P<after_placeholder>.+)$", line)
  33. if m:
  34. bitbake_variable_value = d.getVar(m.group('bitbake_variable_name'), True)
  35. if bitbake_variable_value is None:
  36. bitbake_variable_value = ""
  37. bb.warn("BitBake variable %s not set" % (m.group('bitbake_variable_name')))
  38. line = m.group('before_placeholder') + bitbake_variable_value + m.group('after_placeholder')
  39. found = True
  40. continue
  41. else:
  42. m = re.match(r"^(?P<before_placeholder>.+)@@(?P<bitbake_variable_name>.+)\[(?P<flag_var_name>.+)\]@@(?P<after_placeholder>.+)$", line)
  43. if m:
  44. bitbake_variable_value = (d.getVarFlag(m.group('bitbake_variable_name'), m.group('flag_var_name'), True) or "")
  45. if bitbake_variable_value is None:
  46. bitbake_variable_value = ""
  47. line = m.group('before_placeholder') + bitbake_variable_value + m.group('after_placeholder')
  48. continue
  49. if found:
  50. line = line + "\n"
  51. break
  52. write_lines.append(line)
  53. with open(os.path.join(s, "sw-description"), 'w+') as f:
  54. for line in write_lines:
  55. f.write(line)
  56. def prepare_sw_description(d, s, list_for_cpio):
  57. swupdate_expand_bitbake_variables(d, s)
  58. for file in list_for_cpio:
  59. if file != 'sw-description' and swupdate_is_hash_needed(s, file):
  60. hash = swupdate_get_sha256(s, file)
  61. swupdate_write_sha256(s, file, hash)
  62. signing = d.getVar('SWUPDATE_SIGNING', True)
  63. if signing == "1":
  64. bb.warn('SWUPDATE_SIGNING = "1" is deprecated, falling back to "RSA". It is advised to set it to "RSA" if using RSA signing.')
  65. signing = "RSA"
  66. if signing:
  67. if signing == "CUSTOM":
  68. sign_tool = d.getVar('SWUPDATE_SIGN_TOOL', True)
  69. if sign_tool:
  70. ret = os.system(sign_tool)
  71. if ret != 0:
  72. bb.fatal("Failed to sign with %s" % (sign_tool))
  73. else:
  74. bb.fatal("Custom SWUPDATE_SIGN_TOOL is not given")
  75. elif signing == "RSA":
  76. privkey = d.getVar('SWUPDATE_PRIVATE_KEY', True)
  77. if not privkey:
  78. bb.fatal("SWUPDATE_PRIVATE_KEY isn't set")
  79. if not os.path.exists(privkey):
  80. bb.fatal("SWUPDATE_PRIVATE_KEY %s doesn't exist" % (privkey))
  81. passout = d.getVar('SWUPDATE_PASSWORD_FILE', True)
  82. if passout:
  83. passout = "-passin file:'%s' " % (passout)
  84. else:
  85. passout = ""
  86. signcmd = "openssl dgst -sha256 -sign '%s' %s -out '%s' '%s'" % (
  87. privkey,
  88. passout,
  89. os.path.join(s, 'sw-description.sig'),
  90. os.path.join(s, 'sw-description'))
  91. if os.system(signcmd) != 0:
  92. bb.fatal("Failed to sign sw-description with %s" % (privkey))
  93. elif signing == "CMS":
  94. cms_cert = d.getVar('SWUPDATE_CMS_CERT', True)
  95. if not cms_cert:
  96. bb.fatal("SWUPDATE_CMS_CERT is not set")
  97. if not os.path.exists(cms_cert):
  98. bb.fatal("SWUPDATE_CMS_CERT %s doesn't exist" % (cms_cert))
  99. cms_key = d.getVar('SWUPDATE_CMS_KEY', True)
  100. if not cms_key:
  101. bb.fatal("SWUPDATE_CMS_KEY isn't set")
  102. if not os.path.exists(cms_key):
  103. bb.fatal("SWUPDATE_CMS_KEY %s doesn't exist" % (cms_key))
  104. passout = d.getVar('SWUPDATE_PASSWORD_FILE', True)
  105. if passout:
  106. passout = "-passin file:'%s' " % (passout)
  107. else:
  108. passout = ""
  109. signcmd = "openssl cms -sign -in '%s' -out '%s' -signer '%s' -inkey '%s' %s -outform DER -nosmimecap -binary" % (
  110. os.path.join(s, 'sw-description'),
  111. os.path.join(s, 'sw-description.sig'),
  112. cms_cert,
  113. cms_key,
  114. passout)
  115. if os.system(signcmd) != 0:
  116. bb.fatal("Failed to sign sw-description with %s" % (privkey))
  117. else:
  118. bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism.");