Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/ed25519.py: 23%
70 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.ed25519 import (
10 _ED25519_KEY_SIZE,
11 _ED25519_SIG_SIZE,
12 Ed25519PrivateKey,
13 Ed25519PublicKey,
14)
16if typing.TYPE_CHECKING:
17 from cryptography.hazmat.backends.openssl.backend import Backend
20class _Ed25519PublicKey(Ed25519PublicKey):
21 def __init__(self, backend: "Backend", evp_pkey):
22 self._backend = backend
23 self._evp_pkey = evp_pkey
25 def public_bytes(
26 self,
27 encoding: serialization.Encoding,
28 format: serialization.PublicFormat,
29 ) -> bytes:
30 if (
31 encoding is serialization.Encoding.Raw
32 or format is serialization.PublicFormat.Raw
33 ):
34 if (
35 encoding is not serialization.Encoding.Raw
36 or format is not serialization.PublicFormat.Raw
37 ):
38 raise ValueError(
39 "When using Raw both encoding and format must be Raw"
40 )
42 return self._raw_public_bytes()
44 return self._backend._public_key_bytes(
45 encoding, format, self, self._evp_pkey, None
46 )
48 def _raw_public_bytes(self) -> bytes:
49 buf = self._backend._ffi.new("unsigned char []", _ED25519_KEY_SIZE)
50 buflen = self._backend._ffi.new("size_t *", _ED25519_KEY_SIZE)
51 res = self._backend._lib.EVP_PKEY_get_raw_public_key(
52 self._evp_pkey, buf, buflen
53 )
54 self._backend.openssl_assert(res == 1)
55 self._backend.openssl_assert(buflen[0] == _ED25519_KEY_SIZE)
56 return self._backend._ffi.buffer(buf, _ED25519_KEY_SIZE)[:]
58 def verify(self, signature: bytes, data: bytes) -> None:
59 evp_md_ctx = self._backend._lib.EVP_MD_CTX_new()
60 self._backend.openssl_assert(evp_md_ctx != self._backend._ffi.NULL)
61 evp_md_ctx = self._backend._ffi.gc(
62 evp_md_ctx, self._backend._lib.EVP_MD_CTX_free
63 )
64 res = self._backend._lib.EVP_DigestVerifyInit(
65 evp_md_ctx,
66 self._backend._ffi.NULL,
67 self._backend._ffi.NULL,
68 self._backend._ffi.NULL,
69 self._evp_pkey,
70 )
71 self._backend.openssl_assert(res == 1)
72 res = self._backend._lib.EVP_DigestVerify(
73 evp_md_ctx, signature, len(signature), data, len(data)
74 )
75 if res != 1:
76 self._backend._consume_errors()
77 raise exceptions.InvalidSignature
80class _Ed25519PrivateKey(Ed25519PrivateKey):
81 def __init__(self, backend: "Backend", evp_pkey):
82 self._backend = backend
83 self._evp_pkey = evp_pkey
85 def public_key(self) -> Ed25519PublicKey:
86 buf = self._backend._ffi.new("unsigned char []", _ED25519_KEY_SIZE)
87 buflen = self._backend._ffi.new("size_t *", _ED25519_KEY_SIZE)
88 res = self._backend._lib.EVP_PKEY_get_raw_public_key(
89 self._evp_pkey, buf, buflen
90 )
91 self._backend.openssl_assert(res == 1)
92 self._backend.openssl_assert(buflen[0] == _ED25519_KEY_SIZE)
93 public_bytes = self._backend._ffi.buffer(buf)[:]
94 return self._backend.ed25519_load_public_bytes(public_bytes)
96 def sign(self, data: bytes) -> bytes:
97 evp_md_ctx = self._backend._lib.EVP_MD_CTX_new()
98 self._backend.openssl_assert(evp_md_ctx != self._backend._ffi.NULL)
99 evp_md_ctx = self._backend._ffi.gc(
100 evp_md_ctx, self._backend._lib.EVP_MD_CTX_free
101 )
102 res = self._backend._lib.EVP_DigestSignInit(
103 evp_md_ctx,
104 self._backend._ffi.NULL,
105 self._backend._ffi.NULL,
106 self._backend._ffi.NULL,
107 self._evp_pkey,
108 )
109 self._backend.openssl_assert(res == 1)
110 buf = self._backend._ffi.new("unsigned char[]", _ED25519_SIG_SIZE)
111 buflen = self._backend._ffi.new("size_t *", len(buf))
112 res = self._backend._lib.EVP_DigestSign(
113 evp_md_ctx, buf, buflen, data, len(data)
114 )
115 self._backend.openssl_assert(res == 1)
116 self._backend.openssl_assert(buflen[0] == _ED25519_SIG_SIZE)
117 return self._backend._ffi.buffer(buf, buflen[0])[:]
119 def private_bytes(
120 self,
121 encoding: serialization.Encoding,
122 format: serialization.PrivateFormat,
123 encryption_algorithm: serialization.KeySerializationEncryption,
124 ) -> bytes:
125 if (
126 encoding is serialization.Encoding.Raw
127 or format is serialization.PrivateFormat.Raw
128 ):
129 if (
130 format is not serialization.PrivateFormat.Raw
131 or encoding is not serialization.Encoding.Raw
132 or not isinstance(
133 encryption_algorithm, serialization.NoEncryption
134 )
135 ):
136 raise ValueError(
137 "When using Raw both encoding and format must be Raw "
138 "and encryption_algorithm must be NoEncryption()"
139 )
141 return self._raw_private_bytes()
143 return self._backend._private_key_bytes(
144 encoding, format, encryption_algorithm, self, self._evp_pkey, None
145 )
147 def _raw_private_bytes(self) -> bytes:
148 buf = self._backend._ffi.new("unsigned char []", _ED25519_KEY_SIZE)
149 buflen = self._backend._ffi.new("size_t *", _ED25519_KEY_SIZE)
150 res = self._backend._lib.EVP_PKEY_get_raw_private_key(
151 self._evp_pkey, buf, buflen
152 )
153 self._backend.openssl_assert(res == 1)
154 self._backend.openssl_assert(buflen[0] == _ED25519_KEY_SIZE)
155 return self._backend._ffi.buffer(buf, _ED25519_KEY_SIZE)[:]