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

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. 

4 

5import typing 

6 

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) 

15 

16if typing.TYPE_CHECKING: 

17 from cryptography.hazmat.backends.openssl.backend import Backend 

18 

19 

20class _Ed25519PublicKey(Ed25519PublicKey): 

21 def __init__(self, backend: "Backend", evp_pkey): 

22 self._backend = backend 

23 self._evp_pkey = evp_pkey 

24 

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 ) 

41 

42 return self._raw_public_bytes() 

43 

44 return self._backend._public_key_bytes( 

45 encoding, format, self, self._evp_pkey, None 

46 ) 

47 

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)[:] 

57 

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 

78 

79 

80class _Ed25519PrivateKey(Ed25519PrivateKey): 

81 def __init__(self, backend: "Backend", evp_pkey): 

82 self._backend = backend 

83 self._evp_pkey = evp_pkey 

84 

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) 

95 

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])[:] 

118 

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 ) 

140 

141 return self._raw_private_bytes() 

142 

143 return self._backend._private_key_bytes( 

144 encoding, format, encryption_algorithm, self, self._evp_pkey, None 

145 ) 

146 

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)[:]