aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLianhao Lu <lianhao.lu@intel.com>2018-08-24 18:48:49 +0800
committerLianhao Lu <lianhao.lu@intel.com>2018-08-24 18:48:49 +0800
commita570b0bbe05295b469c975916faf19919c656cd2 (patch)
tree692c16ce232ffb3cbddfb518e2fe56d77672e00b
parenta15a4bc165307623ca0870983cee746e5f761db8 (diff)
Added supporting functions for certificate
Added the supporting functions for sign and verify using certificate. Change-Id: Ic84e773d60c248963e63909cbdae3edd99bd5293 Issue-ID: VNFSDK-144 Signed-off-by: Lianhao Lu <lianhao.lu@intel.com>
-rw-r--r--tests/packager/test_utils.py26
-rw-r--r--tests/resources/signature/ca.crt21
-rw-r--r--tests/resources/signature/manifest.mf9
-rw-r--r--tests/resources/signature/test.crt19
-rw-r--r--tests/resources/signature/test.key27
-rw-r--r--vnfsdk_pkgtools/packager/utils.py56
6 files changed, 158 insertions, 0 deletions
diff --git a/tests/packager/test_utils.py b/tests/packager/test_utils.py
index 91fc72b..3124ea5 100644
--- a/tests/packager/test_utils.py
+++ b/tests/packager/test_utils.py
@@ -14,6 +14,9 @@
#
import os
+import subprocess
+
+import pytest
from vnfsdk_pkgtools.packager import utils
@@ -34,3 +37,26 @@ def test_cal_file_hash_remote(mocker):
self.content = CONTENT
mocker.patch('requests.get', new=FakeRequest)
assert SHA256 == utils.cal_file_hash("", "http://fake", 'sha256')
+
+
+MSG_FILE = "tests/resources/signature/manifest.mf"
+CERT_FILE = "tests/resources/signature/test.crt"
+KEY_FILE = "tests/resources/signature/test.key"
+
+def test_sign_verify_pairwise():
+ cms = utils.sign(MSG_FILE, CERT_FILE, KEY_FILE)
+ # We can't examine the exact content of cms because it contains timestamp
+ assert "---BEGIN CMS---" in cms
+ assert "---END CMS---" in cms
+ utils.verify(MSG_FILE, CERT_FILE, cms, no_verify_cert=True)
+
+
+def test_verify_bad(tmpdir):
+ cms = utils.sign(MSG_FILE, CERT_FILE, KEY_FILE)
+
+ p = tmpdir.join("file_msg.txt")
+ p.write("BAD")
+
+ with pytest.raises(subprocess.CalledProcessError):
+ utils.verify(str(p), CERT_FILE, cms, no_verify_cert=True)
+
diff --git a/tests/resources/signature/ca.crt b/tests/resources/signature/ca.crt
new file mode 100644
index 0000000..89ff01a
--- /dev/null
+++ b/tests/resources/signature/ca.crt
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgIJANdjlIoTLDroMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAlBUMQ8wDQYDVQQIDAZMaXNib2ExDzANBgNVBAcMBkxpc2JvYTEUMBIGA1UE
+CgwLRXhhbXBsZSBPcmcwIBcNMTgwODI0MDYyMDI1WhgPMjExNjAyMTIwNjIwMjVa
+MEUxCzAJBgNVBAYTAlBUMQ8wDQYDVQQIDAZMaXNib2ExDzANBgNVBAcMBkxpc2Jv
+YTEUMBIGA1UECgwLRXhhbXBsZSBPcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDGe3tVz3JvBdkWl7od9ji0XoK8NQBogqSjVluw6ulRf2HR/3XGzehw
+3KskDHkxINpfVDoTqUPaCw3Q4as/lu58FstxRZEDf39XjSNgd6igPMzXaUal7ImK
+hl3Qi+XU7CgexnooJBNvr08y+Tbr53UmzXvWAHpTCvwghB7CvGnWaLSB5kQMgaRt
+BD6Hudri0PKiwN6gdsSjlU00MCq7MSwnWXn1vG7XI7CliRzxWQ4c2Xpm7X82xQyo
+lJNNjkhEY8wwTStFMyDdpD0mJTn1t6Y34KEDC9jJdEK8b6VDggpmnbSlNmsbmBUt
+JqMeiDvIKHnNk1GrjkRRyYb2FsL1qn4dAgMBAAGjUDBOMB0GA1UdDgQWBBRW1/Ag
+e8qM1WlXWB0QXf1u36EYBzAfBgNVHSMEGDAWgBRW1/Age8qM1WlXWB0QXf1u36EY
+BzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCS6WS/w7wyQqljtc+r
+39BPQ4Mbbqlws+GSjDcQn7ffes/PxSTSvKE/NxWrAFiG0Im1jWvBfEiCKDSMuBVg
+C6aZmqYib2TlybXKUEKG9wfS/BFMqYkC2eQybwGjuKcaVlzIEtUctfychkRW6K7r
+mf2FJXxtgrMjM2w6aFyk5n7VE/0rxgd8AznW39Z3Lg2gcmEzEFTOqB7DvXeMZffx
++G45//Id377lakpJGH92ALsCNdKkKZddxxp3554PZNsYRYFQoSsl7wfj7UV7IwNx
+i48xlPZTbB4L0GEtgTxIXcYRC3bWOByjfP0YjOWnFJU6caSI77cQmlRuXg9k3jfD
+2Fvh
+-----END CERTIFICATE-----
diff --git a/tests/resources/signature/manifest.mf b/tests/resources/signature/manifest.mf
new file mode 100644
index 0000000..06895d3
--- /dev/null
+++ b/tests/resources/signature/manifest.mf
@@ -0,0 +1,9 @@
+metadata:
+vnf_product_name: test
+vnf_provider_id: test
+vnf_package_version: 1.0
+vnf_release_data_time: 2017-09-15T15:00:03+08:00
+
+Source: digest
+Algorithm: SHA256
+Hash: 20a480339aa4371099f9503511dcc5a8051ce3884846678ced5611ec64bbfc9c
diff --git a/tests/resources/signature/test.crt b/tests/resources/signature/test.crt
new file mode 100644
index 0000000..63c85d4
--- /dev/null
+++ b/tests/resources/signature/test.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAggCCQDrDujRIFtRTDANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJQ
+VDEPMA0GA1UECAwGTGlzYm9hMQ8wDQYDVQQHDAZMaXNib2ExFDASBgNVBAoMC0V4
+YW1wbGUgT3JnMCAXDTE4MDgyNDA2MjY1OVoYDzIxMTYwMjEyMDYyNjU5WjBdMQsw
+CQYDVQQGEwJQVDEPMA0GA1UECAwGTGlzYm9hMQ8wDQYDVQQHDAZMaXNib2ExFDAS
+BgNVBAoMC0V4YW1wbGUgT3JnMRYwFAYDVQQDDA0qLmV4YW1wbGUub3JnMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwVDDqoO+C5dxgi1nnky+D4qqVdFG
+mX3H4q6zFPUAkve3gElfttuDfbmN+OYCWhvKcjUN1Y2xjt+0aeRJVuQ+eumEX/1F
+76i2t9c66fWPtdZ0V8IuDc2ajNxbKiAwYrwVl3AS2tJ32psHRLvpmLoOVz9UXY0J
+rDwr274Z38wIqEGrUQ9hdOebEggeVu6Mv3pZUBYGGo9VX1/PTZguOaP85nC193Ux
+SJe2+KV6aoc0odiokFmWK2JJrNb8bMjrQcQqp86JMW1DHyon5sF6edTIilxgC+SH
+gapT5hZeoNnh3rAgHiWXF8ZOvho341s+7I78pbEtqCXNbF3VqikFlWmStQIDAQAB
+MA0GCSqGSIb3DQEBCwUAA4IBAQCh8CffE1amceKSb7USEfkpsDbNYo+IWMDyVo9g
+WQOYVIqIFGS8RMzs43Y6nIYJ/9pJUG10Qc4Yq1ZEqsV771Fz6WHx3zlJakVww/Ph
+CxbakjO3EzIHVjEWIu3sUfMdyOeF0ZDHDnfQZYWC17d2jE+s8rH2epl2h1jhi8fS
+i+eT2QDv8lHAM2mdM4jSwoCSsN7FImRxcYPoCxYwVkjVkmHhEMaUdqa1LKY/0YBf
+PFm0pVDCBJZZvKGql44eKiaY/GNW9IyzQFprT8V1rhD1fbTBFXghVGVaUi2Am3JD
++eZYMzd4rzFLZm8bjNm0Oler1UJSR1K91lOEig3M8FTN6JRE
+-----END CERTIFICATE-----
diff --git a/tests/resources/signature/test.key b/tests/resources/signature/test.key
new file mode 100644
index 0000000..06781d1
--- /dev/null
+++ b/tests/resources/signature/test.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAwVDDqoO+C5dxgi1nnky+D4qqVdFGmX3H4q6zFPUAkve3gElf
+ttuDfbmN+OYCWhvKcjUN1Y2xjt+0aeRJVuQ+eumEX/1F76i2t9c66fWPtdZ0V8Iu
+Dc2ajNxbKiAwYrwVl3AS2tJ32psHRLvpmLoOVz9UXY0JrDwr274Z38wIqEGrUQ9h
+dOebEggeVu6Mv3pZUBYGGo9VX1/PTZguOaP85nC193UxSJe2+KV6aoc0odiokFmW
+K2JJrNb8bMjrQcQqp86JMW1DHyon5sF6edTIilxgC+SHgapT5hZeoNnh3rAgHiWX
+F8ZOvho341s+7I78pbEtqCXNbF3VqikFlWmStQIDAQABAoIBAEWZ+pjuDgLGaAvi
+pSgNoXCfEG0NiEnDS7CGDdxByg8gOWVrBZckudcOc9tllPs0flNYXr7A4Wj7ik2F
+8BHk48oFQa/91KxRJlhSmdeanj9uEz11oHc/y6FjxT8Jj+I8rdl0dJVsqdJ/dsJ8
+lcJzWq53Er0MBquIjpHzhAVbxNIvEjQvuIyKPEomrvNN49fR5J7ExH8n1OnkuFRJ
+L4L98inXPtcQF2Xgorh2YwhV0DiY5X88TZMCZ8m7CB0DhwZSMueFWa6Aj4m5G0HQ
+kalXU3bCeBu66s3sXZHuGg1oF3MwwO7BX3/1fg8LoaLEvYHAOXH5PNRUzAgh7/mA
+dneVYoECgYEA69oHQ9VvXGpqHnE5spAtmyJn7v32zXEPUibdqPCNrGXznvzXM+Do
+xHB4K51H8wE/WGT/LGgVcubqr62f/SvmyO6RVOS+DRY4aYKyFif0+7mVHgWhoYOg
+oEaODZrKdxC4SrSYaogsDCH7bdkh1VdJhCDx6ppUGXs9/ZfKJn9kG+0CgYEA0dR9
+BQ6qnrBDrZg7vW/xV/iL/PGsJVBUt7oAkN7g4Ub42eTjAhIPdMxipgAkj6EbhoBO
+KpWELvRqC3oTUVutdTvRhdgummNKToZNaYG7CK5X6bsQh7l6tqLVkE1WqoT4yXvA
+1ez7iOhOsTvugYLlRJd3MTNiKw6c9Pr5ihIHyOkCgYEAsMRtk4LBfzNmq8BS7Skw
+dUhZO39u3dVyFTF6CqeYl3CmIjAAnypfavOcrZupFFGIB5lSwxaTlNXLabYo5hhk
+VY6wsD7szmQsDbBeB0sVSyFxyNmRpbtAxT98MmgkfQ60AZHPdnDvCnzhtBf8Sqis
+OfJzPlFC3QJImOuOIEJ0ZpUCgYAtwj0RYUVsHdxkexJsGYF0Qculeb6k1IPlHTcK
+YNCB0ExsmDG5Pd8JBZltwhI3EFdEWa6yMrEE3GBT6GdWErwdGNJ0cdSX7pdB0KAJ
+JjV3iy241waf0p8kPRZ9xZ/kx+LJbad7/5ZLIP4oQH2e2MDO2IkxvZbm9OTdt+27
+Yns4IQKBgEuQv0JTt+o6/1cwZkMvXDKf0vW2nbPG9gbP3gy9Js0mOG0eWYCsNehO
+DGLViyV2XURCskM4ZSA7Xc71lbCFhOV+jDXEipAjw8S8WJWdTraoF1QV12YEdlL/
+KdcxuJKVX8vdE9UCOxH/wcDG/JXAHX3qrMudJgAp598nyk6g2cNt
+-----END RSA PRIVATE KEY-----
diff --git a/vnfsdk_pkgtools/packager/utils.py b/vnfsdk_pkgtools/packager/utils.py
index 2d74943..7027e2b 100644
--- a/vnfsdk_pkgtools/packager/utils.py
+++ b/vnfsdk_pkgtools/packager/utils.py
@@ -15,11 +15,17 @@
import hashlib
from io import BytesIO
+import logging
import os
+import os.path
import urlparse
+import subprocess
+import tempfile
import requests
+LOG = logging.getLogger(__name__)
+
def _hash_value_for_file(f, hash_function, block_size=2**20):
while True:
@@ -43,3 +49,53 @@ def cal_file_hash(root, path, algo):
else:
with open(os.path.join(root, path), 'rb') as fp:
return _hash_value_for_file(fp, h)
+
+
+def _run_cmd(cmd, **kwargs):
+ if isinstance(cmd, list):
+ args = cmd
+ elif isinstance(cmd, string):
+ args = [cmd]
+ else:
+ raise RuntimeError("cmd must be string or list")
+
+ for key, value in kwargs.iteritems():
+ args.append(key)
+ if value:
+ args.append(value)
+ try:
+ LOG.debug("Executing %s", args)
+ return subprocess.check_output(args)
+ except subprocess.CalledProcessError as e:
+ LOG.error("Executing %s failed with return code %d, output: %s",
+ e.cmd, e.returncode, e.output)
+ raise e
+
+
+def sign(msg_file, cert_file, key_file):
+ args = ["openssl", "cms", "-sign", "-binary", "-nocerts"]
+ kwargs = {
+ '-in': os.path.abspath(msg_file),
+ '-signer': os.path.abspath(cert_file),
+ '-inkey': os.path.abspath(key_file),
+ '-outform': 'PEM',
+ }
+
+ return _run_cmd(args, **kwargs)
+
+
+def verify(msg_file, cert_file, cms, no_verify_cert=False):
+ args = ["openssl", "cms", "-verify"]
+ if no_verify_cert:
+ args.append("-no_signer_cert_verify")
+
+ with tempfile.NamedTemporaryFile() as f:
+ f.write(cms)
+ f.flush()
+ kwargs = {
+ '-in': f.name,
+ '-inform': 'PEM',
+ '-content': os.path.abspath(msg_file),
+ '-certfile': os.path.abspath(cert_file),
+ }
+ return _run_cmd(args, **kwargs)