def OnCertSelect(self, widget, path): """ Invoked when a new cert file has been chosen, either by a file browser or by the user hitting enter in the cert file text widget. """ classify = CertificateRepository.ClassifyCertificate(path) if classify is None: self.certName.SetLabel("") return (certType, cert, needPkey) = classify self.SetRequirePKFile(needPkey) # # Clear name first; if we find one we'll set it # below. # self.certName.SetLabel("") if certType == "PEM": self.certName.SetLabel(cert.get_subject().CN)
def InitEnvironmentWithCert(self, certFile, keyFile): """ Set up the cert mgr to run with the specified cert and file. Do not modify the default identity keys in the repository. """ defaultCert = CertificateRepository.Certificate(certFile, keyFile, self.certRepo) self.defaultIdentity = CertificateRepository.CertificateDescriptor(defaultCert, self.certRepo) log.debug("Cert: %s, Key: %s", certFile, keyFile) log.debug("Loaded identity ---\n%s\n---", self.defaultIdentity.GetVerboseText()) # Lock down the repository so it doesn't get modified. self.certRepo.LockMetadata()
def SetNewCertFile(self, path): """ Invoked when a new cert file has been chosen, either by a file browser or by the user hitting enter in the cert file text widget. """ file, dir = os.path.split(path) root, ext = os.path.splitext(path) sp = os.path.join(dir, "%s.signing_policy" % (root)) print "Check sp file ", sp print "path is ", path if os.path.isfile(sp): # # We have a signing policy. # # Set mode to load SP from a file, and fill in the pathname. # self.setSPMode(self.SPFile) self.signingPolicyFileText.SetValue(sp) self.signingPolicyFileText.SetInsertionPointEnd() self.SetNewSPFile(sp) else: # # if there wasn't one there, clear out the # sp text field so we don't get a spurious value. # self.signingPolicyFileText.SetValue("") self.SetNewSPFile(None) # # Inspect the certificate to determine its name. # Fill in the certName field in the GUI. # try: cert = CertificateRepository.Certificate(path) name = cert.GetShortSubject() print "Got cert ", name self.certName.SetLabel(name) except Exception, e: # # We couldn't load the cert for some reason, clear out the # name field. # self.certName.SetLabel("")
def __init__(self, userProfileDir): """ CertificateManager constructor. userProfileDir - directory in which this user's profile information is kept. The CM uses this directory to store the certificate repository. """ self.userProfileDir = userProfileDir self.certRepoPath = os.path.join(userProfileDir, "certRepo") self.caDir = os.path.join(userProfileDir, "trustedCACerts") self.defaultIdentity = None self.useDefaultDN = None self.useCertFile = None self.useKeyFile = None self.proxyPath = self.GetProxyPath() # Do some initial sanity checking. # user profile directory needs to exist and be writable # system ca cert dir needs to exist and be readable # # TODO: these could vector a message through the user interface # to let the user know of the errors. if not os.path.isdir(self.userProfileDir) or \ not os.access(self.userProfileDir, os.R_OK | os.W_OK): raise Exception("User profile directory %s does not exist or is not writable" \ % (self.userProfileDir)) if not os.path.isdir(self.caDir): os.mkdir(self.caDir) # Configure the certificate mgr. # Attempt to initialize the certificate repository. First try # to initialize one without specifying the create option. try: self.certRepo = CertificateRepository.CertificateRepository(self.certRepoPath, create = 0) log.debug("Opened repository %s", self.certRepoPath) except CertificateRepository.RepoDoesNotExist: # We don't have a cert repo. # Initialize ourselves. self.InitializeRepository()
def InitializeRepository(self): """ Initiailize the cert repository as we don't already have one. We need to first create a new repository (by passing create=1 to the constructor). """ log.debug("initializing repository") try: self.certRepo = CertificateRepository.CertificateRepository(self.certRepoPath, create = 1) except CertificateRepository.RepoAlreadyExists: # We really shouldn't be here. Raise an exception. log.exception("repo already exists") raise Exception, "Received RepoAlreadyExists exception after we determined that it didn't actually exist" self.ImportCACertificates()
def GetProxyCert(self): """ Perform some exhaustive checks to see if there is a valid proxy in place. """ # # The basic scheme here is to test for the various possibilities # of *failure* for there to be a valid cert, and raise the appropriate # exception for each. If we get to the end, we're still in the running # and we can set up the environment. # # Doing it this way makes the code more readable than a deeply-nested # set of if-tests that culminate with success down deep in the nesting. # It also makes it easier to add additional tests if necessary. # # # Check to see if the proxy file exists. # if not os.path.isfile(self.proxyPath): raise NoProxyFound # # Check to see if the proxy file is actually a certificate # of some sort. # try: proxyCert = CertificateRepository.Certificate(self.proxyPath, self.proxyPath, repo = self.GetCertificateRepository()) except: #except crypto.Error: import traceback traceback.print_exc() raise NoProxyFound return proxyCert
def OnImport(self, event): """ User pressed "Import". Doublecheck validity of files. If we're creating a signing policy from the cert, create it, write to a temp file. """ # # First check to see that the filenames aren't empty. # certPath = self.certFileText.GetValue().strip() print "certpath='%s'" % (certPath) if certPath == "": self.ImportFail("No certificate file selected.") return # # Does it exist? # if not os.path.isfile(certPath): self.ImportFail("Certificate file %s does not exist." % (certPath)) return # # Load up a cert object from the certificate. # try: cert = CertificateRepository.Certificate(certPath) except Exception, e: self.ImportFail( "Certificate file %s\ncannot be loaded. Is it really a certificate?" % (certPath)) return
def SetNewSPFile(self, path): """ Invoked when a new signing policy file has been chosen, either by a file browser or by the user hitting enter in the signing policy file text widget. """ # # Inspect the signing policy file to determine its name. # Fill in the spName field in the GUI. # caName = None try: fh = open(path) caName = CertificateRepository.ParseSigningPolicy(fh) except Exception, e: # # We couldn't load the signing policy for some reason, clear out the # name field. # pass
class ImportCACertDialog(wx.Dialog): """ Dialog for importing a new trusted CA certificate. This dialog doesn't actually do the heavy lifting of the import, but does obtain the certificate and signing policy paths and some initial verification. """ # # signing policy modes # SPConstruct = 1 SPFile = 2 def __init__(self, parent, certMgr, id=-1, title="Import Trusted CA Certificate"): wx.Dialog.__init__(self, parent, id, title, size=wx.Size(600, 200), style=wx.CAPTION | wx.RESIZE_BORDER | wx.SYSTEM_MENU) self.certMgr = certMgr self.__build() # # initialize lastFilterIndex for cert file browser. # self.lastFilterIndex = 0 self.lastSPFilterIndex = 0 def Run(self): """ Run the dialog. If successful, returns a tuple (cert filename, signing-policy). Signing-policy is a text string. Otherwise, returns None. """ ret = self.ShowModal() print "Ret is", wx.ID_OK if ret != wx.ID_OK: return None # # Success. On success, the dialog has filled in # self.certFile and self.signingPolicy. # return self.certFile, self.signingPolicy def __build(self): """ Build import dialog. Overall layout: [Intro text] Certificate file: [------------------------------] [Browse] Certificate name: [static text for name] [Signing policy text] [X] Create signing policy from certificate [X] Create signing policy from file Signing policy file: [--------------------------] [ Browse ] ------ [Import] [Cancel] We force the two static text strings on the file lines to be the same size so it's not too ugly. """ topsizer = wx.BoxSizer(wx.VERTICAL) # # Create these and make them align in size. # static1 = wx.StaticText(self, -1, "Certificate file:") static2 = wx.StaticText(self, -1, "Signing policy file:") s1 = static1.GetSize() s2 = static2.GetSize() print "S1=%s S2=%s" % (s1, s2) if s1.GetWidth() > s2.GetWidth(): s2.SetWidth(s1.GetWidth()) static2.SetSize(s2) print "Force s2 to be ", s2 else: s1.SetWidth(s2.GetWidth()) static1.SetSize(s1) print "Force s1 to be ", s1 # # Introductory text. # introText = """Enter the pathname to the CA certificate below, or use the Browse button to browse to it. """ intro = wx.StaticText(self, -1, introText) topsizer.Add(intro, 0, wx.EXPAND) # # Certificate file browser # hb = wx.BoxSizer(wx.HORIZONTAL) topsizer.Add(hb, 0, wx.EXPAND) hb.Add(static1, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3) self.certFileText = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER) hb.Add(self.certFileText, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) wx.EVT_TEXT_ENTER(self, self.certFileText.GetId(), self.OnCertFileEnter) b = wx.Button(self, -1, "Browse") hb.Add(b, 0, wx.ALL, 3) wx.EVT_BUTTON(self, b.GetId(), self.OnCertBrowse) # # Cert name. # hb = wx.BoxSizer(wx.HORIZONTAL) topsizer.Add(hb, 0, wx.EXPAND) hb.Add(wx.StaticText(self, -1, "Certificate name: "), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) self.certName = wx.StaticText(self, -1, "") hb.Add(self.certName, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) # # Separate from SP stuff. # topsizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 4) # # Signing policy text. # spText = """\ Enter the filename of the signing policy for this CA certificate below, or use the Browse button to browse for it. Alternatively, it may be possible to construct the signing policy from the CA certificate. """ sp = wx.StaticText(self, -1, spText) topsizer.Add(sp, 0, wx.EXPAND) # # Signing policy box # # Two radio buttons, plus another text/textctrl/browse button. # rb1 = wx.RadioButton(self, -1, "Construct from certificate", style=wx.RB_GROUP) wx.EVT_RADIOBUTTON( self, rb1.GetId(), lambda event, self=self: self.setSPMode(self.SPConstruct)) self.fileRadioButton = rb2 = wx.RadioButton(self, -1, "Import from file") wx.EVT_RADIOBUTTON( self, rb2.GetId(), lambda event, self=self: self.setSPMode(self.SPFile)) topsizer.Add(rb1, 0, wx.EXPAND | wx.ALL, 3) topsizer.Add(rb2, 0, wx.EXPAND | wx.ALL, 3) # # Hsizer hb for the text label, file location, and browse button # hb = wx.BoxSizer(wx.HORIZONTAL) topsizer.Add(hb, 0, wx.EXPAND | wx.ALL, 3) hb.Add(static2, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3) self.signingPolicyFileText = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER) wx.EVT_TEXT_ENTER(self, self.signingPolicyFileText.GetId(), self.OnSPFileEnter) self.signingPolicyBrowseButton = b = wx.Button(self, -1, "Browse") wx.EVT_BUTTON(self, b.GetId(), self.OnSigningPolicyBrowse) hb.Add(self.signingPolicyFileText, 1, wx.ALL | wx.EXPAND, 3) hb.Add(b, 0, wx.ALL, 3) # # and a hbox with signing policy's CA name. # hb = wx.BoxSizer(wx.HORIZONTAL) topsizer.Add(hb, 0, wx.EXPAND) hb.Add(wx.StaticText(self, -1, "Signing policy for CA: "), 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) self.spName = wx.StaticText(self, -1, "") hb.Add(self.spName, 1, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) # # Import/Cancel buttons # hb = wx.BoxSizer(wx.HORIZONTAL) b = wx.Button(self, -1, "Import") wx.EVT_BUTTON(self, b.GetId(), self.OnImport) hb.Add(b, 0, wx.ALL, 3) b = wx.Button(self, -1, "Cancel") wx.EVT_BUTTON(self, b.GetId(), lambda event, self=self: self.EndModal(wx.ID_CANCEL)) hb.Add(b, 0, wx.ALL, 3) topsizer.Add(hb, 0, wx.ALIGN_RIGHT) # # Default to using file. # self.setSPMode(self.SPFile) # # done with gui setup. # self.SetSizer(topsizer) self.SetAutoLayout(1) self.Fit() def OnCertFileEnter(self, event): print "User hit enter" self.SetNewCertFile(self.certFileText.GetValue()) def OnSPFileEnter(self, event): print "User hit enter on sp" self.SetNewSPFile(self.signingPolicyFileText.GetValue()) def setSPMode(self, mode): self.spMode = mode enable = mode == self.SPFile self.fileRadioButton.SetValue(enable) self.signingPolicyFileText.Enable(enable) self.signingPolicyBrowseButton.Enable(enable) def ImportFail(self, message): """ The import will fail. Show message in a dialog, query the user to see if he wants to try again or not. """ dlg = wx.MessageDialog(self, "%s\n\nRetry import?" % (message), "Import problem", style=wx.YES_NO | wx.YES_DEFAULT) ret = dlg.ShowModal() if ret == wx.ID_YES: print "Retrying" return else: self.EndModal(wx.ID_CANCEL) def OnImport(self, event): """ User pressed "Import". Doublecheck validity of files. If we're creating a signing policy from the cert, create it, write to a temp file. """ # # First check to see that the filenames aren't empty. # certPath = self.certFileText.GetValue().strip() print "certpath='%s'" % (certPath) if certPath == "": self.ImportFail("No certificate file selected.") return # # Does it exist? # if not os.path.isfile(certPath): self.ImportFail("Certificate file %s does not exist." % (certPath)) return # # Load up a cert object from the certificate. # try: cert = CertificateRepository.Certificate(certPath) except Exception, e: self.ImportFail( "Certificate file %s\ncannot be loaded. Is it really a certificate?" % (certPath)) return # # Check to see if we already have this certificate installed. # repo = self.certMgr.GetCertificateRepository() matchingCerts = repo.FindCertificatesWithSubject(str( cert.GetSubject())) validCerts = filter(lambda a: not a.IsExpired(), matchingCerts) if matchingCerts != []: dlg = wx.MessageDialog( self, "Another certificate with this name is already present\n\n" + "Attempt to import anyway?", "Certificate already exists", style=wx.YES_NO | wx.NO_DEFAULT) ret = dlg.ShowModal() if ret == wx.ID_NO: return # # See if we have to construct a signing policy. If we do, do so; otherwise # check the existence of the path to the signing policy file. # if self.spMode == self.SPFile: spFile = self.signingPolicyFileText.GetValue().strip() if spFile == "": self.ImportFail("No signing policy file selected.") return # # Does it exist? # if not os.path.isfile(spFile): self.ImportFail("Signing policy file %s does not exist." % (spFile)) return # # Parse the signing policy. # caName = None try: fh = open(spFile) caName = CertificateRepository.ParseSigningPolicy(fh) fh.close() except Exception, e: self.ImportFail("Signing policy file %s\ncannot be parsed." % (spFile)) return # # See if the CA name in the signing policy matches the subject name # of the certificate. # # Since our parsing may not be perfect, we give the user the option # to go ahead and import anyway. # subj = str(cert.GetSubject()) if caName != subj: dlg = wx.MessageDialog( self, ("Name in certificate does not match name in signing policy:\n" + " certificate: %(subj)s\n" + " signing policy: %(caName)s\n" + "Import anyway?") % locals(), "Error in signing policy", style=wx.YES_NO | wx.NO_DEFAULT) ret = dlg.ShowModal() if ret == wx.ID_NO: return self.signingPolicy = open(spFile).read()
+ " certificate: %(subj)s\n" + " signing policy: %(caName)s\n" + "Import anyway?") % locals(), "Error in signing policy", style=wx.YES_NO | wx.NO_DEFAULT) ret = dlg.ShowModal() if ret == wx.ID_NO: return self.signingPolicy = open(spFile).read() else: # # We need to construct a signing policy. # self.signingPolicy = CertificateRepository.ConstructSigningPolicy( cert) self.certFile = certPath self.EndModal(wx.ID_OK) def OnSigningPolicyBrowse(self, event): """ Browse for a signing policy file. """ # # Defaults for file browser. # dir = file = ""
def OnImport(self, event): """ User pressed "Import". Perform some preliminary tests so that we can report status back to the user and possibly allow him to go back to the dialog to fix things. """ certPath = self.certWidget.GetPath() pkPath = None # # Set this flag to suppress further dialogs. # suppressDialogs = 0 # # Warn if no cert is provided. # if certPath == "": dlg = wx.MessageDialog(self, "No certificate pathname provided.", "Import error", style=wx.OK) dlg.ShowModal() dlg.Destroy() return # # Check for invalid file. # if not os.path.isfile(certPath): dlg = wx.MessageDialog( self, "Certificate pathname %s is not a readable file." % (certPath), "Import error", style=wx.OK) dlg.ShowModal() dlg.Destroy() return # # Attempt to classify the certificate. # classify = CertificateRepository.ClassifyCertificate(certPath) # print "Classify %s returns %s" % (certPath, classify) # # If it fails, we're most likely not going to be able # to import it. Give the user a chance to attempt to import, # though, in case the classify missed something. # if not classify and not suppressDialogs: dlg = wx.MessageDialog( self, "Cannot identify the type of this certificate; it might not be valid\n\n" + "Attempt to import anyway?", "Possibly invalid certificate", style=wx.YES_NO | wx.NO_DEFAULT) rc = dlg.ShowModal() dlg.Destroy() if rc != wx.ID_YES: return else: suppressDialogs = 1 (certType, cert, needPK) = classify if certType == "Unknown" and not suppressDialogs: dlg = wx.MessageDialog( self, "Cannot identify the type of this certificate; it might not be valid\n\n" + "Attempt to import anyway?", "Possibly invalid certificate", style=wx.YES_NO | wx.NO_DEFAULT) rc = dlg.ShowModal() dlg.Destroy() if rc != wx.ID_YES: return else: suppressDialogs = 1 if needPK: # # Check if a private key was entered. # pkPath = self.pkWidget.GetPath() if pkPath == "" and not suppressDialogs: dlg = wx.MessageDialog( self, "Private key file is required, but was not provided.\n\n" + "Attempt to import anyway?", "Private key required.", style=wx.YES_NO | wx.NO_DEFAULT) rc = dlg.ShowModal() dlg.Destroy() if rc != wx.ID_YES: return else: suppressDialogs = 1 if pkPath != "" and not os.path.isfile(pkPath): dlg = wx.MessageDialog( self, "Private key pathname %s is not a readable file." % (pkPath), "Import error", style=wx.OK) dlg.ShowModal() dlg.Destroy() return else: # # If we are PEm and we don't need a private key, that means the # private key is in the same file as the cert. # if certType == "PEM": pkPath = certPath # # Check to see if we already have this certificate installed. # if cert: repo = self.certMgr.GetCertificateRepository() matchingCerts = repo.FindCertificatesWithSubject( str(cert.get_subject())) validCerts = filter(lambda a: not a.IsExpired(), matchingCerts) if validCerts != []: dlg = wx.MessageDialog( self, "Another certificate with this name is already present.\n\n" + "Attempt to import anyway?", "Certificate already exists", style=wx.YES_NO | wx.NO_DEFAULT) ret = dlg.ShowModal() if ret == wx.ID_NO: return self.certType = certType self.certFile = certPath self.pkFile = pkPath self.EndModal(wx.ID_OK)
except: log.exception("Could not retrieve ca certs") if caCerts: #print "Got ca: ", caCerts for caCert, signingPolicy in caCerts: # # See if this one is already installed. # caObj = None try: caObj = CertificateRepository.Certificate( None, certText=caCert) except: log.exception("Error loading cacert") continue # Predicate that returns true for an unexpired certificate # having a subject name of this CA cert. pred = lambda c, der = caObj.GetSubject().as_der(): \ c.GetSubject().as_der() == der and not c.IsExpired() # Determine the list of certs with that name. matchingCerts = list( certMgr.GetCertificateRepository().FindCertificates( pred))