1#!/usr/bin/env python 2 3# Copyright (C) 2017 g10 Code GmbH 4# 5# This file is part of GPGME. 6# 7# GPGME is free software; you can redistribute it and/or modify it 8# under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11# 12# GPGME is distributed in the hope that it will be useful, but WITHOUT 13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 15# Public License for more details. 16# 17# You should have received a copy of the GNU Lesser General Public 18# License along with this program; if not, see <https://www.gnu.org/licenses/>. 19 20from __future__ import absolute_import, print_function, unicode_literals 21 22import gpg 23import itertools 24import time 25 26import support 27support.assert_gpg_version((2, 1, 2)) 28 29del absolute_import, print_function, unicode_literals 30 31alpha = "Alpha <alpha@invalid.example.net>" 32 33with support.EphemeralContext() as ctx: 34 res = ctx.create_key(alpha) 35 36 keys = list(ctx.keylist()) 37 assert len(keys) == 1, "Weird number of keys created" 38 39 key = keys[0] 40 assert key.fpr == res.fpr 41 assert len(key.subkeys) == 2, "Expected one primary key and one subkey" 42 assert key.subkeys[0].expires > 0, "Expected primary key to expire" 43 44 # Try to create a key with the same UID 45 try: 46 ctx.create_key(alpha) 47 assert False, "Expected an error but got none" 48 except gpg.errors.GpgError as e: 49 pass 50 51 # Try to create a key with the same UID, now with force! 52 res2 = ctx.create_key(alpha, force=True) 53 assert res.fpr != res2.fpr 54 55# From here on, we use one context, and create unique UIDs 56uid_counter = 0 57 58 59def make_uid(): 60 global uid_counter 61 uid_counter += 1 62 return "user{0}@invalid.example.org".format(uid_counter) 63 64 65with support.EphemeralContext() as ctx: 66 # Check gpg.constants.create.NOEXPIRE... 67 res = ctx.create_key(make_uid(), expires=False) 68 key = ctx.get_key(res.fpr, secret=True) 69 assert key.fpr == res.fpr 70 assert len(key.subkeys) == 2, "Expected one primary key and one subkey" 71 assert key.subkeys[0].expires == 0, "Expected primary key not to expire" 72 73 t = 2 * 24 * 60 * 60 74 slack = 5 * 60 75 res = ctx.create_key(make_uid(), expires_in=t) 76 key = ctx.get_key(res.fpr, secret=True) 77 assert key.fpr == res.fpr 78 assert len(key.subkeys) == 2, "Expected one primary key and one subkey" 79 assert abs(time.time() + t - key.subkeys[0].expires) < slack, \ 80 "Primary keys expiration time is off" 81 82 # Check capabilities 83 for sign, encrypt, certify, authenticate \ 84 in itertools.product([False, True], 85 [False, True], 86 [False, True], 87 [False, True]): 88 # Filter some out 89 if not (sign or encrypt or certify or authenticate): 90 # This triggers the default capabilities tested before. 91 continue 92 if (sign or encrypt or authenticate) and not certify: 93 # The primary key always certifies. 94 continue 95 96 res = ctx.create_key( 97 make_uid(), 98 algorithm="rsa", 99 sign=sign, 100 encrypt=encrypt, 101 certify=certify, 102 authenticate=authenticate) 103 key = ctx.get_key(res.fpr, secret=True) 104 assert key.fpr == res.fpr 105 assert len(key.subkeys) == 1, \ 106 "Expected no subkey for non-default capabilities" 107 108 p = key.subkeys[0] 109 assert sign == p.can_sign 110 assert encrypt == p.can_encrypt 111 assert certify == p.can_certify 112 assert authenticate == p.can_authenticate 113 114 # Check algorithm 115 res = ctx.create_key(make_uid(), algorithm="rsa") 116 key = ctx.get_key(res.fpr, secret=True) 117 assert key.fpr == res.fpr 118 for k in key.subkeys: 119 assert k.pubkey_algo == 1 120 121 # Check algorithm with size 122 res = ctx.create_key(make_uid(), algorithm="rsa1024") 123 key = ctx.get_key(res.fpr, secret=True) 124 assert key.fpr == res.fpr 125 for k in key.subkeys: 126 assert k.pubkey_algo == 1 127 assert k.length == 1024 128 129 # Check algorithm future-default 130 ctx.create_key(make_uid(), algorithm="future-default") 131 132 # Check passphrase protection 133 recipient = make_uid() 134 passphrase = "streng geheim" 135 res = ctx.create_key(recipient, passphrase=passphrase) 136 ciphertext, _, _ = ctx.encrypt( 137 b"hello there", recipients=[ctx.get_key(res.fpr)]) 138 139 cb_called = False 140 141 def cb(*args): 142 global cb_called 143 cb_called = True 144 return passphrase 145 146 ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK 147 ctx.set_passphrase_cb(cb) 148 149 plaintext, _, _ = ctx.decrypt(ciphertext) 150 assert plaintext == b"hello there" 151 assert cb_called 152