Fixes #2473: Fix encoding of long (>127 character) secrets

This commit is contained in:
Jeremy Stretch 2018-11-07 13:44:16 -05:00
parent c1838104ae
commit 69d829ce8d
3 changed files with 20 additions and 7 deletions

View File

@ -1,3 +1,11 @@
v2.4.8 (FUTURE)
## Bug Fixes
* [#2473](https://github.com/digitalocean/netbox/issues/2473) - Fix encoding of long (>127 character) secrets
---
v2.4.7 (2018-11-06) v2.4.7 (2018-11-06)
## Enhancements ## Enhancements

View File

@ -1,6 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import os import os
import sys
from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
@ -392,6 +393,7 @@ class Secret(ChangeLoggedModel, CustomFieldModel):
s = s.encode('utf8') s = s.encode('utf8')
if len(s) > 65535: if len(s) > 65535:
raise ValueError("Maximum plaintext size is 65535 bytes.") raise ValueError("Maximum plaintext size is 65535 bytes.")
# Minimum ciphertext size is 64 bytes to conceal the length of short secrets. # Minimum ciphertext size is 64 bytes to conceal the length of short secrets.
if len(s) <= 62: if len(s) <= 62:
pad_length = 62 - len(s) pad_length = 62 - len(s)
@ -399,12 +401,14 @@ class Secret(ChangeLoggedModel, CustomFieldModel):
pad_length = 16 - ((len(s) + 2) % 16) pad_length = 16 - ((len(s) + 2) % 16)
else: else:
pad_length = 0 pad_length = 0
return (
chr(len(s) >> 8).encode() + # Python 2 compatibility
chr(len(s) % 256).encode() + if sys.version_info[0] < 3:
s + header = chr(len(s) >> 8) + chr(len(s) % 256)
os.urandom(pad_length) else:
) header = bytes([len(s) >> 8]) + bytes([len(s) % 256])
return header + s + os.urandom(pad_length)
def _unpad(self, s): def _unpad(self, s):
""" """

View File

@ -1,4 +1,5 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import string
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from django.conf import settings from django.conf import settings
@ -88,7 +89,7 @@ class SecretTestCase(TestCase):
""" """
Test basic encryption and decryption functionality using a random master key. Test basic encryption and decryption functionality using a random master key.
""" """
plaintext = "FooBar123" plaintext = string.printable * 2
secret_key = generate_random_key() secret_key = generate_random_key()
s = Secret(plaintext=plaintext) s = Secret(plaintext=plaintext)
s.encrypt(secret_key) s.encrypt(secret_key)