Exemplo n.º 1
0
def make_test_orgentry() -> keycard.OrgEntry:
    '''Generates an organizational entry for testing purposes'''

    # Primary signing key
    pskey = nacl.signing.SigningKey(
        b'msvXw(nII<Qm6oBHc+92xwRI3>VFF-RcZ=7DEu3|', Base85Encoder)

    orgcard = keycard.OrgEntry()
    orgcard.set_fields({
        'Name':
        'Acme Widgets, Inc.',
        'Contact-Admin':
        'c590b44c-798d-4055-8d72-725a7942f3f6/acme.com',
        'Language':
        'en',
        'Domain':
        'acme.com',
        'Primary-Verification-Key':
        'ED25519:)8id(gE02^S<{3H>9B;X4{DuYcb`%wo^mC&1lN88',
        'Encryption-Key':
        'CURVE25519:@b?cjpeY;<&y+LSOA&yUQ&ZIrp(JGt{W$*V>ATLG'
    })

    # Organization sign, hash, and verify

    rv = orgcard.generate_hash('BLAKE2B-256')
    assert not rv.error(), 'entry failed to hash'

    pskeystring = CryptoString()
    pskeystring.set('ED25519:' + base64.b85encode(pskey.encode()).decode())
    rv = orgcard.sign(pskeystring, 'Organization')
    assert not rv.error(), 'Unexpected RetVal error %s' % rv.error()
    assert orgcard.signatures['Organization'], 'entry failed to user sign'

    ovkey = nacl.signing.VerifyKey(pskey.verify_key.encode())
    ovkeystring = CryptoString()
    ovkeystring.prefix = 'ED25519'
    ovkeystring.data = base64.b85encode(ovkey.encode()).decode()

    rv = orgcard.verify_signature(ovkeystring, 'Organization')
    assert not rv.error(), 'org entry failed to verify'

    status = orgcard.is_compliant()
    assert not status.error(), f"OrgEntry wasn't compliant: {str(status)}"

    return orgcard
Exemplo n.º 2
0
def test_is_compliant_org():
    '''Tests compliance testing for the OrgEntry class'''

    # Organization signing key
    oskey = nacl.signing.SigningKey(
        b'msvXw(nII<Qm6oBHc+92xwRI3>VFF-RcZ=7DEu3|', Base85Encoder)

    orgcard = keycard.OrgEntry()
    orgcard.set_fields({
        'Name':
        'Acme Widgets, Inc',
        'Contact-Admin':
        '54025843-bacc-40cc-a0e4-df48a099c2f3/example.com',
        'Contact-Abuse':
        '54025843-bacc-40cc-a0e4-df48a099c2f3/example.com',
        'Language':
        'en',
        'Primary-Verification-Key':
        'ED25519:7dfD==!Jmt4cDtQDBxYa7(dV|N$}8mYwe$=RZuW|',
        'Encryption-Key':
        'CURVE25519:_`UC|vltn_%P5}~vwV^)oY){#uvQSSy(dOD_l(yE'
    })

    # sign and verify

    okeystring = CryptoString()
    okeystring.set('ED25519:' + base64.b85encode(oskey.encode()).decode())
    rv = orgcard.sign(okeystring, 'Organization')
    assert not rv.error(), 'Unexpected RetVal error %s' % rv.error()
    assert orgcard.signatures['Organization'], 'entry failed to user sign'

    ovkey = nacl.signing.VerifyKey(oskey.verify_key.encode())
    ovkeystring = CryptoString()
    ovkeystring.prefix = 'ED25519'
    ovkeystring.data = base64.b85encode(ovkey.encode()).decode()

    rv = orgcard.verify_signature(ovkeystring, 'Organization')
    assert not rv.error(), 'entry failed to org verify'

    rv = orgcard.generate_hash('BLAKE2B-256')
    assert not rv.error(), 'entry failed to hash'

    status = orgcard.is_compliant()
    assert not status.error(), f"OrgEntry wasn't compliant: {str(status)}"
Exemplo n.º 3
0
def init_server(dbconn) -> dict:
    '''Adds basic data to the database as if setupconfig had been run. Returns data needed for 
	tests, such as the keys'''

    # Start off by generating the org's root keycard entry and add to the database

    cur = dbconn.cursor()
    card = keycard.Keycard()

    root_entry = keycard.OrgEntry()
    root_entry.set_fields({
        'Name':
        'Example, Inc.',
        'Contact-Admin':
        'c590b44c-798d-4055-8d72-725a7942f3f6/acme.com',
        'Language':
        'en',
        'Domain':
        'example.com',
        'Primary-Verification-Key':
        'ED25519:r#r*RiXIN-0n)BzP3bv`LA&t4LFEQNF0Q@$N~RF*',
        'Encryption-Key':
        'CURVE25519:SNhj2K`hgBd8>G>lW$!pXiM7S-B!Fbd9jT2&{{Az'
    })

    initial_ovkey = CryptoString(
        r'ED25519:r#r*RiXIN-0n)BzP3bv`LA&t4LFEQNF0Q@$N~RF*')
    initial_oskey = CryptoString(
        r'ED25519:{UNQmjYhz<(-ikOBYoEQpXPt<irxUF*nq25PoW=_')
    initial_ovhash = CryptoString(
        r'BLAKE2B-256:ag29av@TUvh-V5KaB2l}H=m?|w`}dvkS1S1&{cMo')

    initial_epubkey = CryptoString(
        r'CURVE25519:SNhj2K`hgBd8>G>lW$!pXiM7S-B!Fbd9jT2&{{Az')
    initial_eprivkey = CryptoString(
        r'CURVE25519:WSHgOhi+bg=<bO^4UoJGF-z9`+TBN{ds?7RZ;w3o')
    initial_epubhash = CryptoString(
        r'BLAKE2B-256:-Zz4O7J;m#-rB)2llQ*xTHjtblwm&kruUVa_v(&W')

    # Organization hash, sign, and verify

    rv = root_entry.generate_hash('BLAKE2B-256')
    assert not rv.error(), 'entry failed to hash'

    rv = root_entry.sign(initial_oskey, 'Organization')
    assert not rv.error(), 'Unexpected RetVal error %s' % rv.error()
    assert root_entry.signatures['Organization'], 'entry failed to org sign'

    rv = root_entry.verify_signature(initial_ovkey, 'Organization')
    assert not rv.error(), 'org entry failed to verify'

    status = root_entry.is_compliant()
    assert not status.error(), f"OrgEntry wasn't compliant: {str(status)}"

    card.entries.append(root_entry)
    cur.execute("INSERT INTO keycards(owner,creationtime,index,entry,fingerprint) " \
     "VALUES('organization',%s,%s,%s,%s);",
     (root_entry.fields['Timestamp'],root_entry.fields['Index'],
      root_entry.make_bytestring(-1).decode(), root_entry.hash))

    cur.execute(
        "INSERT INTO orgkeys(creationtime, pubkey, privkey, purpose, fingerprint) "
        "VALUES(%s,%s,%s,'encrypt',%s);",
        (root_entry.fields['Timestamp'], initial_epubkey.as_string(),
         initial_eprivkey.as_string(), initial_epubhash.as_string()))

    cur.execute(
        "INSERT INTO orgkeys(creationtime, pubkey, privkey, purpose, fingerprint) "
        "VALUES(%s,%s,%s,'sign',%s);",
        (root_entry.fields['Timestamp'], initial_ovkey.as_string(),
         initial_oskey.as_string(), initial_ovhash.as_string()))

    cur.close()
    dbconn.commit()
    cur = dbconn.cursor()

    # Sleep for 1 second in order for the new entry's timestamp to be useful
    time.sleep(1)

    # Chain a new entry to the root

    status = card.chain(initial_oskey, True)
    assert not status.error(), f'keycard chain failed: {status}'

    # Save the keys to a separate RetVal so we can keep using status for return codes
    keys = status

    new_entry = status['entry']
    new_entry.prev_hash = root_entry.hash
    new_entry.generate_hash('BLAKE2B-256')
    assert not status.error(), f'chained entry failed to hash: {status}'

    status = card.verify()
    assert not status.error(), f'keycard failed to verify: {status}'

    cur.execute("INSERT INTO keycards(owner,creationtime,index,entry,fingerprint) " \
     "VALUES('organization',%s,%s,%s,%s);",
     (new_entry.fields['Timestamp'],new_entry.fields['Index'],
      new_entry.make_bytestring(-1).decode(), new_entry.hash))

    cur.execute(
        "INSERT INTO orgkeys(creationtime, pubkey, privkey, purpose, fingerprint) "
        "VALUES(%s,%s,%s,'sign',%s);",
        (new_entry.fields['Timestamp'], keys['sign.public'],
         keys['sign.private'], keys['sign.pubhash']))

    cur.execute(
        "INSERT INTO orgkeys(creationtime, pubkey, privkey, purpose, fingerprint) "
        "VALUES(%s,%s,%s,'encrypt',%s);",
        (new_entry.fields['Timestamp'], keys['encrypt.public'],
         keys['encrypt.private'], keys['encrypt.pubhash']))

    if keys.has_value('altsign.public'):
        cur.execute(
            "INSERT INTO orgkeys(creationtime, pubkey, privkey, purpose, fingerprint) "
            "VALUES(%s,%s,%s,'altsign',%s);",
            (new_entry.fields['Timestamp'], keys['altsign.public'],
             keys['altsign.private'], keys['altsign.pubhash']))

    # Prereg the admin account
    admin_wid = 'ae406c5e-2673-4d3e-af20-91325d9623ca'
    regcode = 'Undamaged Shining Amaretto Improve Scuttle Uptake'
    cur.execute(
        f"INSERT INTO prereg(wid, uid, domain, regcode) VALUES('{admin_wid}', 'admin', "
        f"'example.com', '{regcode}');")

    # Set up abuse/support forwarding to admin
    abuse_wid = 'f8cfdbdf-62fe-4275-b490-736f5fdc82e3'
    cur.execute(
        "INSERT INTO workspaces(wid, uid, domain, password, status, wtype) "
        f"VALUES('{abuse_wid}', 'abuse', 'example.com', '-', 'active', 'alias');"
    )
    cur.execute(f"INSERT INTO aliases(wid, alias) VALUES('{abuse_wid}', "
                f"'{'/'.join([admin_wid, 'example.com'])}');")

    support_wid = 'f0309ef1-a155-4655-836f-55173cc1bc3b'
    cur.execute(
        f"INSERT INTO workspaces(wid, uid, domain, password, status, wtype) "
        f"VALUES('{support_wid}', 'support', 'example.com', '-', 'active', 'alias');"
    )
    cur.execute(f"INSERT INTO aliases(wid, alias) VALUES('{support_wid}', "
                f"'{'/'.join([admin_wid, 'example.com'])}');")

    cur.close()
    dbconn.commit()

    return {
        'ovkey': keys['sign.public'],
        'oskey': keys['sign.private'],
        'oekey': keys['encrypt.public'],
        'odkey': keys['encrypt.private'],
        'admin_wid': admin_wid,
        'admin_regcode': regcode,
        'root_org_entry': root_entry,
        'second_org_entry': new_entry
    }
Exemplo n.º 4
0
config['org_sign'] = pskey['sign']

# Using Python's string substitution to compose SQL commands is normally really, really 
# dangerous because it enables SQL injection attacks. We're using only our own data generated in 
# this script, so it's not so terrible

cur.execute(f"INSERT INTO orgkeys(creationtime, pubkey, privkey, purpose, fingerprint) "
			f"VALUES('{ekey['timestamp']}', '{ekey['public']}', '{ekey['private']}', 'encrypt', "
			f"'{ekey['fingerprint']}');")

cur.execute(f"INSERT INTO orgkeys(creationtime, pubkey, privkey, purpose, fingerprint) "
			f"VALUES('{pskey['timestamp']}', '{pskey['verify']}', '{pskey['sign']}', 'sign', "
			f"'{pskey['fingerprint']}');")


rootentry = keycard.OrgEntry()
rootentry.set_fields({
	'Name' : config['org_name'],
	'Primary-Verification-Key' : config['org_verify'],
	'Encryption-Key' : config['org_encrypt']
})

if 'org_language' in config and len(config['org_language']) > 0:
	rootentry.set_field('Language', config['org_language'])

# preregister the admin account and put into the serverconfig

admin_wid = str(uuid.uuid4())
regcode = make_diceware()
cur.execute(f"INSERT INTO prereg(wid, uid, domain, regcode) VALUES('{admin_wid}', 'admin', "
	f"'{config['org_domain']}', '{regcode}');")