1 from abc
import ABCMeta, abstractmethod
2 from opcua.ua import CryptographyNone, SecurityPolicy
3 from opcua.ua import MessageSecurityMode
7 CRYPTOGRAPHY_AVAILABLE =
True 9 CRYPTOGRAPHY_AVAILABLE =
False 12 POLICY_NONE_URI =
'http://opcfoundation.org/UA/SecurityPolicy#None' 17 Raise exception if cryptography module is not available. 18 Call this function in constructors. 20 if not CRYPTOGRAPHY_AVAILABLE:
21 raise UaError(
"Can't use {0}, cryptography module is not installed".format(obj.__class__.__name__))
26 Abstract base class for cryptographic signature algorithm 29 __metaclass__ = ABCMeta
40 class Verifier(object):
42 Abstract base class for cryptographic signature verification 45 __metaclass__ = ABCMeta
56 class Encryptor(object):
58 Abstract base class for encryption algorithm 61 __metaclass__ = ABCMeta
76 class Decryptor(object):
78 Abstract base class for decryption algorithm 81 __metaclass__ = ABCMeta
96 class Cryptography(CryptographyNone):
98 Security policy: Sign or SignAndEncrypt 106 assert mode
in (MessageSecurityMode.Sign,
107 MessageSecurityMode.SignAndEncrypt)
112 Size of plain text block for block cipher. 115 return self.Encryptor.plain_block_size()
120 Size of encrypted text block for block cipher. 123 return self.Encryptor.encrypted_block_size()
128 Create padding for a block of given size. 129 plain_size = size + len(padding) + signature_size() 130 plain_size = N * plain_block_size() 134 block_size = self.Encryptor.plain_block_size()
137 rem = block_size - rem
138 return bytes(bytearray([rem])) * (rem + 1)
146 return self.Signer.signature_size()
149 return self.Signer.signature(data)
152 return self.Verifier.signature_size()
155 self.Verifier.verify(data, sig)
159 assert len(data) % self.Encryptor.plain_block_size() == 0
160 return self.Encryptor.encrypt(data)
165 return self.Decryptor.decrypt(data)
170 pad_size = bytearray(data[-1:])[0] + 1
171 return data[:-pad_size]
186 return uacrypto.sign_sha1(self.
client_pk, data)
194 self.
key_size = self.server_cert.public_key().key_size // 8
200 uacrypto.verify_sha1(self.
server_cert, data, signature)
205 def __init__(self, server_cert, enc_fn, padding_size):
208 self.
key_size = self.server_cert.public_key().key_size // 8
221 for i
in range(0, len(data), block_size):
222 encrypted += self.
encryptor(self.server_cert.public_key(),
223 data[i: i + block_size])
229 def __init__(self, client_pk, dec_fn, padding_size):
245 for i
in range(0, len(data), block_size):
247 data[i: i + block_size])
258 return uacrypto.sha1_size()
261 return uacrypto.hmac_sha1(self.
key, data)
271 return uacrypto.sha1_size()
274 expected = uacrypto.hmac_sha1(self.
key, data)
275 if signature != expected:
276 raise uacrypto.InvalidSignature
283 self.
cipher = uacrypto.cipher_aes_cbc(key, init_vec)
286 return self.cipher.algorithm.key_size // 8
289 return self.cipher.algorithm.key_size // 8
292 return uacrypto.cipher_encrypt(self.
cipher, data)
299 self.
cipher = uacrypto.cipher_aes_cbc(key, init_vec)
302 return self.cipher.algorithm.key_size // 8
305 return self.cipher.algorithm.key_size // 8
308 return uacrypto.cipher_decrypt(self.
cipher, data)
313 Security Basic 128Rsa15 314 A suite of algorithms that uses RSA15 as Key-Wrap-algorithm 315 and 128-Bit (16 bytes) for encryption algorithms. 316 - SymmetricSignatureAlgorithm - HmacSha1 317 (http://www.w3.org/2000/09/xmldsig#hmac-sha1) 318 - SymmetricEncryptionAlgorithm - Aes128 319 (http://www.w3.org/2001/04/xmlenc#aes128-cbc) 320 - AsymmetricSignatureAlgorithm - RsaSha1 321 (http://www.w3.org/2000/09/xmldsig#rsa-sha1) 322 - AsymmetricKeyWrapAlgorithm - KwRsa15 323 (http://www.w3.org/2001/04/xmlenc#rsa-1_5) 324 - AsymmetricEncryptionAlgorithm - Rsa15 325 (http://www.w3.org/2001/04/xmlenc#rsa-1_5) 326 - KeyDerivationAlgorithm - PSha1 327 (http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/dk/p_sha1) 328 - DerivedSignatureKeyLength - 128 (16 bytes) 329 - MinAsymmetricKeyLength - 1024 (128 bytes) 330 - MaxAsymmetricKeyLength - 2048 (256 bytes) 331 - CertificateSignatureAlgorithm - Sha1 333 If a certificate or any certificate in the chain is not signed with 334 a hash that is Sha1 or stronger then the certificate shall be rejected. 337 URI =
"http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15" 338 signature_key_size = 16
339 symmetric_key_size = 16
340 AsymmetricEncryptionURI =
"http://www.w3.org/2001/04/xmlenc#rsa-1_5" 344 return uacrypto.encrypt_rsa15(pubkey, data)
346 def __init__(self, server_cert, client_cert, client_pk, mode):
348 if isinstance(server_cert, bytes):
349 server_cert = uacrypto.x509_from_der(server_cert)
353 MessageSecurityMode.SignAndEncrypt)
354 self.asymmetric_cryptography.Signer =
SignerRsa(client_pk)
355 self.asymmetric_cryptography.Verifier =
VerifierRsa(server_cert)
357 server_cert, uacrypto.encrypt_rsa15, 11)
359 client_pk, uacrypto.decrypt_rsa15, 11)
368 (sigkey, key, init_vec) = uacrypto.p_sha1(nonce2, nonce1, key_sizes)
369 self.symmetric_cryptography.Signer =
SignerAesCbc(sigkey)
372 (sigkey, key, init_vec) = uacrypto.p_sha1(nonce1, nonce2, key_sizes)
380 A suite of algorithms that are for 256-Bit (32 bytes) encryption, 382 - SymmetricSignatureAlgorithm - HmacSha1 383 (http://www.w3.org/2000/09/xmldsig#hmac-sha1) 384 - SymmetricEncryptionAlgorithm - Aes256 385 (http://www.w3.org/2001/04/xmlenc#aes256-cbc) 386 - AsymmetricSignatureAlgorithm - RsaSha1 387 (http://www.w3.org/2000/09/xmldsig#rsa-sha1) 388 - AsymmetricKeyWrapAlgorithm - KwRsaOaep 389 (http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p) 390 - AsymmetricEncryptionAlgorithm - RsaOaep 391 (http://www.w3.org/2001/04/xmlenc#rsa-oaep) 392 - KeyDerivationAlgorithm - PSha1 393 (http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/dk/p_sha1) 394 - DerivedSignatureKeyLength - 192 (24 bytes) 395 - MinAsymmetricKeyLength - 1024 (128 bytes) 396 - MaxAsymmetricKeyLength - 2048 (256 bytes) 397 - CertificateSignatureAlgorithm - Sha1 399 If a certificate or any certificate in the chain is not signed with 400 a hash that is Sha1 or stronger then the certificate shall be rejected. 403 URI =
"http://opcfoundation.org/UA/SecurityPolicy#Basic256" 404 signature_key_size = 24
405 symmetric_key_size = 32
406 AsymmetricEncryptionURI =
"http://www.w3.org/2001/04/xmlenc#rsa-oaep" 410 return uacrypto.encrypt_rsa_oaep(pubkey, data)
412 def __init__(self, server_cert, client_cert, client_pk, mode):
414 if isinstance(server_cert, bytes):
415 server_cert = uacrypto.x509_from_der(server_cert)
419 MessageSecurityMode.SignAndEncrypt)
420 self.asymmetric_cryptography.Signer =
SignerRsa(client_pk)
421 self.asymmetric_cryptography.Verifier =
VerifierRsa(server_cert)
423 server_cert, uacrypto.encrypt_rsa_oaep, 42)
425 client_pk, uacrypto.decrypt_rsa_oaep, 42)
435 (sigkey, key, init_vec) = uacrypto.p_sha1(nonce2, nonce1, key_sizes)
436 self.symmetric_cryptography.Signer =
SignerAesCbc(sigkey)
439 (sigkey, key, init_vec) = uacrypto.p_sha1(nonce1, nonce2, key_sizes)
446 Encrypt data with pubkey using an asymmetric algorithm. 447 The algorithm is selected by policy_uri. 448 Returns a tuple (encrypted_data, algorithm_uri) 450 for cls
in [SecurityPolicyBasic256, SecurityPolicyBasic128Rsa15]:
451 if policy_uri == cls.URI:
452 return (cls.encrypt_asymmetric(pubkey, data),
453 cls.AsymmetricEncryptionURI)
454 if not policy_uri
or policy_uri == POLICY_NONE_URI:
456 raise UaError(
"Unsupported security policy `{0}`".format(policy_uri))
def signature(self, data)
def encrypted_block_size(self)
def __init__(self, client_pk)
def plain_block_size(self)
def signature(self, data)
def verify(self, data, signature)
def encrypted_block_size(self)
def signature(self, data)
def make_symmetric_key(self, nonce1, nonce2)
def encrypted_block_size(self)
def encrypted_block_size(self)
def plain_block_size(self)
def verify(self, data, sig)
def plain_block_size(self)
def plain_block_size(self)
def __init__(self, mode=MessageSecurityMode.Sign)
def verify(self, data, signature)
def __init__(self, server_cert)
def make_symmetric_key(self, nonce1, nonce2)
def __init__(self, client_pk, dec_fn, padding_size)
def verify(self, data, signature)
def remove_padding(self, data)
def plain_block_size(self)
def require_cryptography(obj)
def plain_block_size(self)
def __init__(self, key, init_vec)
def encrypted_block_size(self)
def encrypted_block_size(self)
def __init__(self, server_cert, client_cert, client_pk, mode)
def signature(self, data)
def __init__(self, server_cert, client_cert, client_pk, mode)
def __init__(self, server_cert, enc_fn, padding_size)
def encrypt_asymmetric(pubkey, data)
def vsignature_size(self)
def __init__(self, key, init_vec)
def encrypted_block_size(self)
def encrypt_asymmetric(pubkey, data, policy_uri)
def encrypt_asymmetric(pubkey, data)
def min_padding_size(self)
def plain_block_size(self)