Debugged/fixed revoked key file generation.
This commit is contained in:
parent
0b207f6123
commit
4450ba773f
8
scripts/revoke-user-cert
Normal file → Executable file
8
scripts/revoke-user-cert
Normal file → Executable file
@ -21,7 +21,7 @@ from Crypto.PublicKey import RSA
|
||||
|
||||
parser = argparse.ArgumentParser(description='Revoke a Tatu-generated user SSH certificate.')
|
||||
parser.add_argument('--projid', '-P', required=True)
|
||||
parser.add_argument('--serial', '-K', required=True)
|
||||
parser.add_argument('--serial', '-S', required=True)
|
||||
parser.add_argument('--tatu-url', default= 'http://127.0.0.1:18322',
|
||||
help='URL of the Tatu API')
|
||||
args = parser.parse_args()
|
||||
@ -38,12 +38,6 @@ if not args.serial.isdigit():
|
||||
|
||||
server = args.tatu_url
|
||||
|
||||
body = {
|
||||
'serial': args.serial,
|
||||
'auth_id': auth_id,
|
||||
'key.pub': pubkeytext
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
server + '/revokeduserkeys/' + auth_id,
|
||||
data=json.dumps({'serial': args.serial})
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
import falcon
|
||||
from oslo_log import log as logging
|
||||
from tatu import models
|
||||
from tatu.api import models
|
||||
from tatu.db.persistence import SQLAlchemySessionManager
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -311,7 +311,7 @@ class RevokedUserKeys(object):
|
||||
self.session,
|
||||
auth_id,
|
||||
serial=req.body.get('serial', None),
|
||||
key=req.body.get('key_id', None),
|
||||
key_id=req.body.get('key_id', None),
|
||||
cert=req.body.get('cert', None)
|
||||
)
|
||||
resp.status = falcon.HTTP_OK
|
||||
|
@ -67,16 +67,20 @@ def createAuthority(session, auth_id):
|
||||
class UserCert(Base):
|
||||
__tablename__ = 'user_certs'
|
||||
|
||||
user_id = sa.Column(sa.String(36), primary_key=True)
|
||||
fingerprint = sa.Column(sa.String(60), primary_key=True)
|
||||
serial = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
|
||||
user_id = sa.Column(sa.String(36))
|
||||
fingerprint = sa.Column(sa.String(60))
|
||||
auth_id = sa.Column(sa.String(36), sa.ForeignKey('authorities.auth_id'))
|
||||
cert = sa.Column(sa.Text)
|
||||
serial = sa.Column(sa.Integer, index=True, autoincrement=True)
|
||||
revoked = sa.Column(sa.Boolean, default=False)
|
||||
|
||||
sa.Index('idx_user_finger', UserCert.user_id, UserCert.fingerprint, unique=True)
|
||||
|
||||
|
||||
def getUserCert(session, user_id, fingerprint):
|
||||
return session.query(UserCert).get([user_id, fingerprint])
|
||||
return session.query(UserCert).filter(
|
||||
UserCert.user_id == user_id).filter(
|
||||
UserCert.fingerprint == fingerprint).one_or_none()
|
||||
|
||||
|
||||
def getUserCerts(session):
|
||||
@ -90,21 +94,22 @@ def createUserCert(session, user_id, auth_id, pub):
|
||||
raise falcon.HTTPNotFound(
|
||||
description='No Authority found with that ID')
|
||||
fingerprint = sshpubkeys.SSHKey(pub).hash_md5()
|
||||
certRecord = session.query(UserCert).get([user_id, fingerprint])
|
||||
certRecord = getUserCert(session, user_id, fingerprint)
|
||||
if certRecord is not None:
|
||||
return certRecord
|
||||
cert = generateCert(getAuthUserKey(auth), pub,
|
||||
principals='admin,root')
|
||||
if cert is None:
|
||||
raise falcon.HTTPInternalServerError(
|
||||
"Failed to generate the certificate")
|
||||
user = UserCert(
|
||||
user_id=user_id,
|
||||
fingerprint=fingerprint,
|
||||
auth_id=auth_id,
|
||||
cert=cert
|
||||
)
|
||||
session.add(user)
|
||||
session.flush()
|
||||
user.cert = generateCert(getAuthUserKey(auth), pub, user=True,
|
||||
principals='admin,root', serial=user.serial)
|
||||
if user.cert is None:
|
||||
raise falcon.HTTPInternalServerError(
|
||||
"Failed to generate the certificate")
|
||||
|
||||
session.commit()
|
||||
return user
|
||||
|
||||
@ -124,7 +129,9 @@ def getRevokedKeysBase64(session, auth_id):
|
||||
description='No Authority found with that ID')
|
||||
serials = [k.serial for k in session.query(RevokedKey).filter(
|
||||
RevokedKey.auth_id == auth_id)]
|
||||
return revokedKeysBase64(getAuthUserKey(auth), serials)
|
||||
user_key = RSA.importKey(getAuthUserKey(auth))
|
||||
user_pub_key = user_key.publickey().exportKey('OpenSSH')
|
||||
return revokedKeysBase64(user_pub_key, serials)
|
||||
|
||||
|
||||
def revokeUserKey(session, auth_id, serial=None, key_id=None, cert=None):
|
||||
@ -140,7 +147,7 @@ def revokeUserKey(session, auth_id, serial=None, key_id=None, cert=None):
|
||||
raise falcon.HTTPBadRequest(
|
||||
"Incorrect CA ID for serial # {}".format(serial))
|
||||
ser = serial
|
||||
elif key is not None:
|
||||
elif key_id is not None:
|
||||
# TODO(pino): look up the UserCert by key id and get the serial number
|
||||
pass
|
||||
elif cert is not None:
|
||||
@ -242,8 +249,7 @@ def createHostCert(session, token_id, host_id, pub):
|
||||
certRecord = session.query(HostCert).get([host_id, fingerprint])
|
||||
if certRecord is not None:
|
||||
raise falcon.HTTPConflict('This public key is already signed.')
|
||||
cert = generateCert(getAuthHostKey(auth), pub,
|
||||
hostname=token.hostname)
|
||||
cert = generateCert(getAuthHostKey(auth), pub, user=False)
|
||||
if cert == '':
|
||||
raise falcon.HTTPInternalServerError(
|
||||
"Failed to generate the certificate")
|
||||
|
@ -22,7 +22,7 @@ def random_uuid():
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def generateCert(auth_key, entity_key, hostname=None, principals='root'):
|
||||
def generateCert(auth_key, entity_key, user=True, principals='root', serial=0):
|
||||
# Temporarily write the authority private key, entity public key to files
|
||||
temp_dir = mkdtemp()
|
||||
ca_file = '/'.join([temp_dir, 'ca_key'])
|
||||
@ -37,8 +37,8 @@ def generateCert(auth_key, entity_key, hostname=None, principals='root'):
|
||||
with open(pub_file, "w", 0o644) as text_file:
|
||||
text_file.write(entity_key)
|
||||
args = ['ssh-keygen', '-s', ca_file, '-I', 'testID', '-V',
|
||||
'-1d:+365d']
|
||||
if hostname is None:
|
||||
'-1d:+365d', '-z', str(serial)]
|
||||
if user:
|
||||
args.extend(['-n', principals, pub_file])
|
||||
else:
|
||||
args.extend(['-h', pub_file])
|
||||
@ -51,22 +51,19 @@ def generateCert(auth_key, entity_key, hostname=None, principals='root'):
|
||||
return cert
|
||||
|
||||
|
||||
def revokedKeysBase64(auth_key, serial_list):
|
||||
def revokedKeysBase64(ca_public, serial_list):
|
||||
# Temporarily write the authority private key and list of serials
|
||||
temp_dir = mkdtemp()
|
||||
ca_file = '/'.join([temp_dir, 'ca_key'])
|
||||
ca_file = '/'.join([temp_dir, 'ca_public'])
|
||||
serials_file = '/'.join([temp_dir, 'serials'])
|
||||
revoked_file = '/'.join([temp_dir, 'revoked'])
|
||||
try:
|
||||
fd = os.open(ca_file, os.O_WRONLY | os.O_CREAT, 0o600)
|
||||
os.close(fd)
|
||||
with open(ca_file, "w") as text_file:
|
||||
text_file.write(auth_key)
|
||||
with open(ca_file, "w", 0o644) as text_file:
|
||||
text_file.write(ca_public)
|
||||
with open(serials_file, "w", 0o644) as text_file:
|
||||
for s in serial_list:
|
||||
text_file.write("serial: " + s + "\n")
|
||||
args = ['ssh-keygen', '-s', ca_file, '-k', '-f', revoked_file,
|
||||
serials_file]
|
||||
text_file.write("serial: {}\n".format(s))
|
||||
args = ['ssh-keygen', '-k', '-f', revoked_file, '-s', ca_file, serials_file]
|
||||
subprocess.check_output(args, stderr=subprocess.STDOUT)
|
||||
# Return the base64 encoded contents of the revoked keys file
|
||||
with open(revoked_file, 'r') as text_file:
|
||||
|
Loading…
Reference in New Issue
Block a user