def create_cert(urn, issuer_key=None, issuer_cert=None, ca=False, public_key=None, lifeDays=1825, email=None): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If ca then mark this as a CA certificate (can sign other certs). lifeDays is the lifetime of the supplied cert - default is 1825 (5 years). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) subject = dict() subject['CN'] = dotted[:64] if email: subject['emailAddress'] = email newgid = GID(create=True, subject=subject, urn=urn, lifeDays=lifeDays) if public_key is None: # create a new key pair keys = Keypair(create=True) else: # use the specified public key file keys = Keypair() keys.load_pubkey_from_file(public_key) newgid.set_pubkey(keys) newgid.set_is_ca(ca) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key, str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert, str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
def create_cert(urn, issuer_key=None, issuer_cert=None, ca=False, public_key=None, lifeDays=1825, email=None): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If ca then mark this as a CA certificate (can sign other certs). lifeDays is the lifetime of the supplied cert - default is 1825 (5 years). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) subject = dict() subject['CN'] = dotted[:64] if email: subject['emailAddress'] = email newgid = GID(create=True, subject=subject, urn=urn, lifeDays=lifeDays) if public_key is None: # create a new key pair keys = Keypair(create=True) else: # use the specified public key file keys = Keypair() keys.load_pubkey_from_file(public_key) newgid.set_pubkey(keys) newgid.set_is_ca(ca) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key,str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert,str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
def CreateSlice(user_cert, urn_req=None): # Is this user allowed to create a slice? # first get the user with this cert username = get_username_from_cert(user_cert) try: User.objects.get(username=username) except User.DoesNotExist: raise Exception("Unknown user %s." % username) if urn_req: # check the requested URN urn = URN(urn=urn_req) # make sure that we would generate the same urn if using the # same name (i.e. authority is the same...) urn_gen = get_slice_urn(urn.getName()) if urn_gen != urn_req: raise BadURNException( "The requested URN is not one that would be generated" " by this clearinghouse. Requested was %s, but generated" " is %s" % (urn_req, urn_gen) ) else: # Generate a unique URN for the slice urn_req = create_slice_urn() try: slice_gid = create_x509_cert(urn_req)[0] except Exception as exc: logger.error("Could not create slice. Error\n %s" % traceback.format_exc()) raise Exception("Failed to create slice %s." % urn_req) # Now get the user GID which will have permissions on this slice. # It doesnt have the chain but should be signed # by this CHs cert, which should also be a trusted # root at any federated AM. So everyone can verify it as is. # Note that if a user from a different CH (installed # as trusted by this CH for some reason) called this method, # that user would be used here - and can still get a valid slice try: user_gid = gid.GID(string=user_cert) except Exception, exc: logger.error("CreateSlice failed to create user_gid from SSL client cert: %s", traceback.format_exc()) raise Exception("Failed to create slice %s. Cant get user GID from SSL client certificate." % urn_req, exc)
def urn_to_username(urn): """Create a valid username from a URN. This creates the username by taking the authority part of the URN, and the name part of the URN and joining them with "@". Any characters other than letters, digits, '@', '-', '_', '+', and '.' are replace with '_'. e.g. "urn:publicid:IDN+stanford:expedient%26+user+jnaous" becomes "jnaous@expedient_26.stanford" The authority part of the URN is truncated to 155 characters, and the name part is truncated to 100 characters. @param urn: a urn to turn into a username @type urn: C{str} @return: a valid username @rtype: C{str} """ invalid_chars_re = re.compile(r"[^\w@+.-]") urn = URN(urn=str(urn)) auth = urn.getAuthority() auth = auth.split("//") auth.reverse() auth = ".".join(auth) if len(auth) > 150: auth = auth[:150] name = urn.getName() if len(name) > 100: name = name[:100] username = name + "@" + auth # replace all invalid chars with _ username = invalid_chars_re.sub("_", username) assert (len(username) <= 255) return username
def urn_to_username(urn): """Create a valid username from a URN. This creates the username by taking the authority part of the URN, and the name part of the URN and joining them with "@". Any characters other than letters, digits, '@', '-', '_', '+', and '.' are replace with '_'. e.g. "urn:publicid:IDN+stanford:expedient%26+user+jnaous" becomes "jnaous@expedient_26.stanford" The authority part of the URN is truncated to 155 characters, and the name part is truncated to 100 characters. @param urn: a urn to turn into a username @type urn: C{str} @return: a valid username @rtype: C{str} """ invalid_chars_re = re.compile(r"[^\w@+.-]") urn = URN(urn=str(urn)) auth = urn.getAuthority() auth = auth.split("//") auth.reverse() auth = ".".join(auth) if len(auth) > 150: auth = auth[:150] name = urn.getName() if len(name) > 100: name =name[:100] username = name + "@" + auth # replace all invalid chars with _ username = invalid_chars_re.sub("_", username) assert(len(username) <= 255) return username
def get_ch_urn(): """Get the URN for Expedient as a clearinghouse. @return: The URN @rtype: C{str} """ return URN( settings.GCF_BASE_NAME, "authority", "sa", ).urn_string()
def get_user_urn(username): """Get a user's URN @param username: The username of the user whose URN we want. @type username: C{str} @return: The URN @rtype: C{str} """ return URN(str(settings.GCF_BASE_NAME), str("user"), str(username)).urn_string()
def create_cert(urn, issuer_key=None, issuer_cert=None, intermediate=False): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If intermediate then mark this as an intermediate CA certificate (can sign). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) newgid = GID(create=True, subject=dotted[:64], urn=urn) keys = Keypair(create=True) newgid.set_pubkey(keys) if intermediate: # This cert will be able to sign certificates newgid.set_intermediate_ca(intermediate) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key,str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert,str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
def get_username_from_cert(cert_string): try: gid = GID(string=cert_string) # extract the URN in the subjectAltName urn_str = gid.get_urn() logger.debug("URN: %s" % urn_str) except: logger.warn("Failed to get certificate from string.") logger.warn(traceback.format_exc()) return cert_string try: urn = URN(urn=str(urn_str)) except ValueError: return cert_string # check if this user is one of ours home_urn = get_user_urn(urn.getName()) if home_urn == urn.urn_string(): username = urn.getName() else: username = urn_to_username(urn.urn_string()) logger.debug("Returning username %s" % username) return username
def create_cert(urn, issuer_key=None, issuer_cert=None, intermediate=False): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If intermediate then mark this as an intermediate CA certificate (can sign). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) newgid = GID(create=True, subject=dotted[:64], urn=urn) keys = Keypair(create=True) newgid.set_pubkey(keys) if intermediate: # This cert will be able to sign certificates newgid.set_intermediate_ca(intermediate) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key, str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert, str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
def get_slice_urn(name): """Get the URN for a slice with name C{name}. @param name: Name of the slice. Must be unique. @type name: C{str} @return: a slice URN @rtype: C{str} """ return URN( settings.GCF_BASE_NAME, "slice", name, ).urn_string()