I have found two mistakes in stickynotes.py, but I have installed old 
Crypto module which has slightly different way of encrypting/decrypting.

The first one is that it refuses to create encrypted stickynote from empty 
node which is, according to the documentation, proper way to create 
encrypted stycky note.
@g.command('stickynoteenc')
def stickynoteenc_f(event, rekey=False):
    """ Launch editable 'sticky note' for the encrypted node """
    if not encOK:
        g.es('no en/decryption - need python-crypto module')
        return
    if not __ENCKEY[0] or rekey:
        sn_getenckey()
    c = event['c']
    p = c.p
    v = p.v

    def focusin():
        if v is c.p.v:
            decoded = sn_decode(v.b)
            if decoded is None:
                return
            if decoded != nf.toPlainText():
                # only when needed to avoid scroll jumping
                nf.setPlainText(decoded)
            nf.setWindowTitle(p.h)
            nf.dirty = False

    def focusout():
        if not nf.dirty:
            return
        enc = sn_encode(str(nf.toPlainText()))
        if v.b != enc:
            v.b = enc
            v.setDirty()
            # Fix #249: Leo and Stickynote plugin do not request to save
            c.setChanged(True)
        nf.dirty = False
        p = c.p
        if p.v is v:
            c.selectPosition(c.p)
        c.redraw()

    if rekey:
        unsecret = sn_decode(v.b)
        if unsecret is None:
            return
        sn_getenckey()
        secret = sn_encode(unsecret)
        v.b = secret
    // this is new - check if it is old note already encrypted
    if v.b:
        decoded = sn_decode(v.b)
        if decoded is None:
            return
    else:
        // creating new encrypted note
        decoded = v.b
    nf = mknote(c,p, focusin=focusin, focusout=focusout)
    nf.setPlainText(decoded)
    if rekey:
        g.es("Key updated, data decoded with new key shown in window")

See the red colored code.

The other mistake is in padding string. It is necessary to pad bytes not 
unicode strings.

def sn_encode(s): s1 = s.encode('utf8') pad = b' '*(16-len(s1)%16) txta = 
AES.new(__ENCKEY[0]).encrypt(s1 + pad) # for old Crypto module # txta = 
AES.new(__ENCKEY[0], AES.MODE_EAX).encrypt(s1 + pad) # for pycryptodome txt 
= base64.b64encode(txta) txt = str(txt, 'utf-8') wrapped = 
textwrap.wrap(txt, break_long_words=True) return '\n'.join(wrapped) 


With this two changes it works for me although I get crashes if calling 
AES.new as in pycryptodome.

The encryption / decryption itself must be handled separately to check if 
we have new or old Crypto module.
The old one doesn't have AES.MODE_EAX.

def get_encoder():
    key = __ENCKEY[0]
    if hasattr(AES, 'MODE_EAX'):
        return AES.new(key, AES.MODE_EAX)
    else:
        return AES.new(key)
# txt = get_encoder().encrypt(s1 + pad)

# or

# decoded = get_encoder().decrypt(s1)



HTH Vitalije

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/leo-editor/f308bd7c-b3ec-48e5-9a9f-63f6f37f87d2%40googlegroups.com.

Reply via email to