Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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("")
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
    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()
Ejemplo n.º 6
0
    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 = ""
Ejemplo n.º 11
0
    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))