Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/ed448.py: 25%
72 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +0000
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
5import typing
7from cryptography import exceptions
8from cryptography.hazmat.primitives import serialization
9from cryptography.hazmat.primitives.asymmetric.ed448 import (
10 Ed448PrivateKey,
11 Ed448PublicKey,
12)
14if typing.TYPE_CHECKING:
15 from cryptography.hazmat.backends.openssl.backend import Backend
17_ED448_KEY_SIZE = 57
18_ED448_SIG_SIZE = 114
21class _Ed448PublicKey(Ed448PublicKey):
22 def __init__(self, backend: "Backend", evp_pkey):
23 self._backend = backend
24 self._evp_pkey = evp_pkey
26 def public_bytes(
27 self,
28 encoding: serialization.Encoding,
29 format: serialization.PublicFormat,
30 ) -> bytes:
31 if (
32 encoding is serialization.Encoding.Raw
33 or format is serialization.PublicFormat.Raw
34 ):
35 if (
36 encoding is not serialization.Encoding.Raw
37 or format is not serialization.PublicFormat.Raw
38 ):
39 raise ValueError(
40 "When using Raw both encoding and format must be Raw"
41 )
43 return self._raw_public_bytes()
45 return self._backend._public_key_bytes(
46 encoding, format, self, self._evp_pkey, None
47 )
49 def _raw_public_bytes(self) -> bytes:
50 buf = self._backend._ffi.new("unsigned char []", _ED448_KEY_SIZE)
51 buflen = self._backend._ffi.new("size_t *", _ED448_KEY_SIZE)
52 res = self._backend._lib.EVP_PKEY_get_raw_public_key(
53 self._evp_pkey, buf, buflen
54 )
55 self._backend.openssl_assert(res == 1)
56 self._backend.openssl_assert(buflen[0] == _ED448_KEY_SIZE)
57 return self._backend._ffi.buffer(buf, _ED448_KEY_SIZE)[:]
59 def verify(self, signature: bytes, data: bytes) -> None:
60 evp_md_ctx = self._backend._lib.EVP_MD_CTX_new()
61 self._backend.openssl_assert(evp_md_ctx != self._backend._ffi.NULL)
62 evp_md_ctx = self._backend._ffi.gc(
63 evp_md_ctx, self._backend._lib.EVP_MD_CTX_free
64 )
65 res = self._backend._lib.EVP_DigestVerifyInit(
66 evp_md_ctx,
67 self._backend._ffi.NULL,
68 self._backend._ffi.NULL,
69 self._backend._ffi.NULL,
70 self._evp_pkey,
71 )
72 self._backend.openssl_assert(res == 1)
73 res = self._backend._lib.EVP_DigestVerify(
74 evp_md_ctx, signature, len(signature), data, len(data)
75 )
76 if res != 1:
77 self._backend._consume_errors()
78 raise exceptions.InvalidSignature
81class _Ed448PrivateKey(Ed448PrivateKey):
82 def __init__(self, backend: "Backend", evp_pkey):
83 self._backend = backend
84 self._evp_pkey = evp_pkey
86 def public_key(self) -> Ed448PublicKey:
87 buf = self._backend._ffi.new("unsigned char []", _ED448_KEY_SIZE)
88 buflen = self._backend._ffi.new("size_t *", _ED448_KEY_SIZE)
89 res = self._backend._lib.EVP_PKEY_get_raw_public_key(
90 self._evp_pkey, buf, buflen
91 )
92 self._backend.openssl_assert(res == 1)
93 self._backend.openssl_assert(buflen[0] == _ED448_KEY_SIZE)
94 public_bytes = self._backend._ffi.buffer(buf)[:]
95 return self._backend.ed448_load_public_bytes(public_bytes)
97 def sign(self, data: bytes) -> bytes:
98 evp_md_ctx = self._backend._lib.EVP_MD_CTX_new()
99 self._backend.openssl_assert(evp_md_ctx != self._backend._ffi.NULL)
100 evp_md_ctx = self._backend._ffi.gc(
101 evp_md_ctx, self._backend._lib.EVP_MD_CTX_free
102 )
103 res = self._backend._lib.EVP_DigestSignInit(
104 evp_md_ctx,
105 self._backend._ffi.NULL,
106 self._backend._ffi.NULL,
107 self._backend._ffi.NULL,
108 self._evp_pkey,
109 )
110 self._backend.openssl_assert(res == 1)
111 buf = self._backend._ffi.new("unsigned char[]", _ED448_SIG_SIZE)
112 buflen = self._backend._ffi.new("size_t *", len(buf))
113 res = self._backend._lib.EVP_DigestSign(
114 evp_md_ctx, buf, buflen, data, len(data)
115 )
116 self._backend.openssl_assert(res == 1)
117 self._backend.openssl_assert(buflen[0] == _ED448_SIG_SIZE)
118 return self._backend._ffi.buffer(buf, buflen[0])[:]
120 def private_bytes(
121 self,
122 encoding: serialization.Encoding,
123 format: serialization.PrivateFormat,
124 encryption_algorithm: serialization.KeySerializationEncryption,
125 ) -> bytes:
126 if (
127 encoding is serialization.Encoding.Raw
128 or format is serialization.PrivateFormat.Raw
129 ):
130 if (
131 format is not serialization.PrivateFormat.Raw
132 or encoding is not serialization.Encoding.Raw
133 or not isinstance(
134 encryption_algorithm, serialization.NoEncryption
135 )
136 ):
137 raise ValueError(
138 "When using Raw both encoding and format must be Raw "
139 "and encryption_algorithm must be NoEncryption()"
140 )
142 return self._raw_private_bytes()
144 return self._backend._private_key_bytes(
145 encoding, format, encryption_algorithm, self, self._evp_pkey, None
146 )
148 def _raw_private_bytes(self) -> bytes:
149 buf = self._backend._ffi.new("unsigned char []", _ED448_KEY_SIZE)
150 buflen = self._backend._ffi.new("size_t *", _ED448_KEY_SIZE)
151 res = self._backend._lib.EVP_PKEY_get_raw_private_key(
152 self._evp_pkey, buf, buflen
153 )
154 self._backend.openssl_assert(res == 1)
155 self._backend.openssl_assert(buflen[0] == _ED448_KEY_SIZE)
156 return self._backend._ffi.buffer(buf, _ED448_KEY_SIZE)[:]