Beispiel #1
0
def importCertificateDialog(repView):
    """
    Let the user import a certificate. First brings up a file selection
    dialog, then asks for trust settings for the certificate being imported.
    """
    certificate = None
    app = wx.GetApp()
    res = Util.showFileDialog(app.mainFrame,
                              _(u"Choose a certificate to import"), u"", u"",
                              _(u"PEM files|*.pem;*.crt|All files (*.*)|*.*"),
                              wx.OPEN)

    (cmd, dir, filename) = res

    if cmd == wx.ID_OK:
        # dir and filename are unicode
        path = os.path.join(dir, filename)

        try:
            x509 = X509.load_cert(path)

            fprint = utils.fingerprint(x509)
            purpose = certificatePurpose(x509)
            # Note: the order of choices must match the selections code below
            choices = [_(u"Trust this certificate.")]
            if purpose & constants.PURPOSE_CA:
                choices += [
                    _(u"Trust this certificate to sign site certificates.")
                ]

            dlg = dialogs.ImportCertificateDialog(app.mainFrame, purpose,
                                                  fprint, x509, choices)
            trust = constants.TRUST_NONE
            if dlg.ShowModal() == wx.ID_OK:
                selections = dlg.GetSelections()
                # Note: this code must match the choices above
                for sel in selections:
                    if sel == 0:
                        trust |= constants.TRUST_AUTHENTICITY
                    if sel == 1:
                        trust |= constants.TRUST_SERVER
                certificate = importCertificate(x509, fprint, trust, repView)
            dlg.Destroy()

        except utils.CertificateException, e:
            wx.MessageBox(e.__unicode__(),
                          messages.ERROR,
                          parent=wx.GetApp().mainFrame)

        except Exception, e:
            log.exception(e)
            wx.MessageBox(_(
                u"Could not add certificate from: %(path)s\nCheck the path and try again."
            ) % {'path': path},
                          messages.ERROR,
                          parent=wx.GetApp().mainFrame)
Beispiel #2
0
def importCertificateDialog(repView):
    """
    Let the user import a certificate. First brings up a file selection
    dialog, then asks for trust settings for the certificate being imported.
    """
    certificate = None
    app = wx.GetApp()
    res = Util.showFileDialog(app.mainFrame,
                              _(u"Choose a certificate to import"),
                              u"",
                              u"",
                              _(u"PEM files|*.pem;*.crt|All files (*.*)|*.*"),
                              wx.OPEN)

    (cmd, dir, filename) = res

    if cmd  == wx.ID_OK:
        # dir and filename are unicode
        path = os.path.join(dir, filename)

        try:
            x509 = X509.load_cert(path)

            fprint = utils.fingerprint(x509)
            purpose = certificatePurpose(x509)
            # Note: the order of choices must match the selections code below
            choices = [_(u"Trust this certificate.")]
            if purpose & constants.PURPOSE_CA:
                choices += [_(u"Trust this certificate to sign site certificates.")]

            dlg = dialogs.ImportCertificateDialog(app.mainFrame,
                                       purpose,
                                       fprint,
                                       x509,
                                       choices)
            trust = constants.TRUST_NONE
            if dlg.ShowModal() == wx.ID_OK:
                selections = dlg.GetSelections()
                # Note: this code must match the choices above
                for sel in selections:
                    if sel == 0:
                        trust |= constants.TRUST_AUTHENTICITY
                    if sel == 1:
                        trust |= constants.TRUST_SERVER
                certificate = importCertificate(x509, fprint, trust, repView)
            dlg.Destroy()

        except utils.CertificateException, e:
            wx.MessageBox (e.__unicode__(), messages.ERROR,
                           parent=wx.GetApp().mainFrame)

        except Exception, e:
            log.exception(e)
            wx.MessageBox (_(u"Could not add certificate from: %(path)s\nCheck the path and try again.") % {'path': path},
                           messages.ERROR,
                           parent=wx.GetApp().mainFrame)
Beispiel #3
0
def askTrustServerCertificate(host, pem, reconnect):
    """
    Ask user if they would like to trust the certificate that was returned by
    the server. This will only happen if the certificate is not already
    trusted, either by trust chain or explicitly.

    @note: If you want to reconnect on background thread, pass in a dummy
           reconnect and reconnect manually after receiving True.
    
    @param host:      The host we think we are connected with.
    @param pem:       The certificate in PEM format.
    @param reconnect: The reconnect callback that will be called if the
                      user chooses to trust the certificate.
    @return:          True if user chose to trust, False otherwise.
    """
    from osaf.framework.certstore import dialogs, certificate
    global trusted_until_shutdown_site_certs

    repositoryView = wx.GetApp().UIRepositoryView
    x509 = X509.load_cert_string(pem)
    untrustedCertificate = certificate.findCertificate(repositoryView, pem)
    dlg = dialogs.TrustServerCertificateDialog(wx.GetApp().mainFrame,
                                               x509,
                                               host,
                                               untrustedCertificate)
    try:
        if dlg.ShowModal() == wx.ID_OK:
            selection = dlg.GetSelection()

            if selection == 0:
                trusted_until_shutdown_site_certs += [pem]
            else:
                if untrustedCertificate is not None:
                    untrustedCertificate.trust |= constants.TRUST_AUTHENTICITY
                else:
                    fingerprint = utils.fingerprint(x509)
                    certificate.importCertificate(x509, fingerprint,
                                       constants.TRUST_AUTHENTICITY,
                                       repositoryView)
                # In either case here (a known, untrusted cert, or a
                # completely untrusted cert), we have made a change
                # and we need to commit so other views can see it.
                repositoryView.commit()
            
            reconnect()

            return True
    finally:
        dlg.Destroy()

    return False
def askTrustServerCertificate(host, pem, reconnect):
    """
    Ask user if they would like to trust the certificate that was returned by
    the server. This will only happen if the certificate is not already
    trusted, either by trust chain or explicitly.

    @note: If you want to reconnect on background thread, pass in a dummy
           reconnect and reconnect manually after receiving True.
    
    @param host:      The host we think we are connected with.
    @param pem:       The certificate in PEM format.
    @param reconnect: The reconnect callback that will be called if the
                      user chooses to trust the certificate.
    @return:          True if user chose to trust, False otherwise.
    """
    from osaf.framework.certstore import dialogs, certificate
    global trusted_until_shutdown_site_certs

    repositoryView = wx.GetApp().UIRepositoryView
    x509 = X509.load_cert_string(pem)
    untrustedCertificate = certificate.findCertificate(repositoryView, pem)
    dlg = dialogs.TrustServerCertificateDialog(wx.GetApp().mainFrame, x509,
                                               host, untrustedCertificate)
    try:
        if dlg.ShowModal() == wx.ID_OK:
            selection = dlg.GetSelection()

            if selection == 0:
                trusted_until_shutdown_site_certs += [pem]
            else:
                if untrustedCertificate is not None:
                    untrustedCertificate.trust |= constants.TRUST_AUTHENTICITY
                else:
                    fingerprint = utils.fingerprint(x509)
                    certificate.importCertificate(x509, fingerprint,
                                                  constants.TRUST_AUTHENTICITY,
                                                  repositoryView)
                # In either case here (a known, untrusted cert, or a
                # completely untrusted cert), we have made a change
                # and we need to commit so other views can see it.
                repositoryView.commit()

            reconnect()

            return True
    finally:
        dlg.Destroy()

    return False
Beispiel #5
0
    def testCertificateCache(self):
        pemRoot = '''-----BEGIN CERTIFICATE-----
MIIDpzCCAxCgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBmjELMAkGA1UEBhMCVVMx
CzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRowGAYDVQQKExFv
c2Fmb3VuZGF0aW9uLm9yZzELMAkGA1UECxMCQ0ExEDAOBgNVBAMTB09TQUYgQ0Ex
KzApBgkqhkiG9w0BCQEWHGhvc3RtYXN0ZXJAb3NhZm91bmRhdGlvbi5vcmcwHhcN
MDQwNjAyMjEzNTIzWhcNMjkwNTI3MjEzNTIzWjCBmjELMAkGA1UEBhMCVVMxCzAJ
BgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRowGAYDVQQKExFvc2Fm
b3VuZGF0aW9uLm9yZzELMAkGA1UECxMCQ0ExEDAOBgNVBAMTB09TQUYgQ0ExKzAp
BgkqhkiG9w0BCQEWHGhvc3RtYXN0ZXJAb3NhZm91bmRhdGlvbi5vcmcwgZ8wDQYJ
KoZIhvcNAQEBBQADgY0AMIGJAoGBAMvKQY9ElPz4UOhYwKPhbHpSzxxGXxQHiOGu
QDV9HuTaTD53cs4xhTau5nLrbqR6qkOpaxgq4+xGZGXwwdrl6vABXGamBAIS8U+C
IoxMZmdi1zNCHpALjrUOr5zG+l5lbxKMzzfbBgz0EvnxdyUW3JzWlFA7gtKwNeq9
8BbIVNIRAgMBAAGjgfowgfcwHQYDVR0OBBYEFFAUmTv7d1YAmmssTPTcaE3FWgdL
MIHHBgNVHSMEgb8wgbyAFFAUmTv7d1YAmmssTPTcaE3FWgdLoYGgpIGdMIGaMQsw
CQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x
GjAYBgNVBAoTEW9zYWZvdW5kYXRpb24ub3JnMQswCQYDVQQLEwJDQTEQMA4GA1UE
AxMHT1NBRiBDQTErMCkGCSqGSIb3DQEJARYcaG9zdG1hc3RlckBvc2Fmb3VuZGF0
aW9uLm9yZ4IBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAAdPk2l4
bQBw41mQvTLGFVUx89oEqmlW8fMh06/PhNyKPvA+Ip/HL4fl71A8aGYINA2KGQeE
Mi6jbcmKpkTked0C7KzayFkggv/SZtmeibzOjQJbO5WQCRgYuF9t7Rijk7oiAt3U
3rOIG1GsNPeKaSKyc+Bpqd9phY+fPNsZf8b4
-----END CERTIFICATE-----'''
        
        self.assert_(ssl.certificateCache == [], 'cache should start empty')
        ssl.getContext(self.view) # set cache
        self.assert_(ssl.certificateCache != [], 'cache should have an entry after getting a context')
        
        x509 = X509.load_cert_string(pemRoot)
        fingerprint = utils.fingerprint(x509)
        cert = certificate.importCertificate(x509,
                                             fingerprint,
                                             constants.TRUST_AUTHENTICITY | constants.TRUST_SERVER,
                                             self.view)
        self.assert_(ssl.certificateCache == [], 'cache should have been cleared after adding a cert')

        ssl.getContext(self.view) # set cache
        cert.trust = 0
        self.assert_(ssl.certificateCache == [], 'cache should have been cleared after changing cert.trust attribute')

        ssl.getContext(self.view) # set cache
        del cert.trust
        self.assert_(ssl.certificateCache == [], 'cache should have been cleared after deleting cert.trust attribute')

        ssl.getContext(self.view) # set cache
        cert.delete()
        self.assert_(ssl.certificateCache == [], 'cache should have been cleared after removing a cert')
Beispiel #6
0
    def _importAndFind(self, pem, trust):
        x509 = X509.load_cert_string(pem)
        fingerprint = utils.fingerprint(x509)
        certificate.importCertificate(x509, fingerprint, trust, self.view)

        view = self.view

        matchingCerts = FilteredCollection(
            'fpCertQuery' + fingerprint,
            itsView=view,
            source=utils.getExtent(certificate.Certificate, view, exact=True),
            filterExpression=u"view.findValue(uuid, 'fingerprint') == '%s'" %
            fingerprint,
            filterAttributes=['fingerprint'])

        self.assert_(len(matchingCerts) == 1)

        return iter(matchingCerts).next()
Beispiel #7
0
    def _importAndFind(self, pem, trust):
        x509 = X509.load_cert_string(pem)
        fingerprint = utils.fingerprint(x509)
        certificate.importCertificate(x509,
                                      fingerprint,
                                      trust,
                                      self.view)
        
        view = self.view

        matchingCerts = FilteredCollection('fpCertQuery' + fingerprint,
                                           itsView=view,
                                           source=utils.getExtent(certificate.Certificate, view, exact=True),
                                           filterExpression=u"view.findValue(uuid, 'fingerprint') == '%s'" % fingerprint,
                                           filterAttributes=['fingerprint'])
        
        self.assert_(len(matchingCerts) == 1)
        
        return iter(matchingCerts).next()
Beispiel #8
0
def loadCerts(parcel, moduleName, filename=u'cacert.pem'):
    # Load cacert.pem into the repository

    import os, sys
    import logging

    from M2Crypto import X509

    log = logging.getLogger(__name__)

    if isinstance(filename, unicode):
        filename = filename.encode('utf8')

    chop = -1

    cert = schema.ns('osaf.framework.certstore', parcel)
    lobType = schema.itemFor(schema.Lob, parcel.itsView)

    from osaf.framework.certstore import utils, constants

    lastLine = ''
    pem = []

    certificates = 0
    itsName = None
    
    for line in open(
        os.path.join(
            os.path.dirname(sys.modules[moduleName].__file__),filename
        ), 'rU'
    ):
        if line[:3] == '===':
            itsName = lastLine
            itsName = itsName[:chop]
        elif line[:chop] == '-----BEGIN CERTIFICATE-----':
            pem = [line]
        elif line[:chop] == '-----END CERTIFICATE-----':
            pem.append(line[:chop])
            x509 = X509.load_cert_string(''.join(pem))

            if itsName is not None:
                commonName = itsName
                itsName = itsName.replace('/', '_')
            else:
                commonName = x509.get_subject().commonName or ''

            if not x509.verify():
                log.warn('Skipping certificate, does not verify: %s' % \
                         (commonName))
                #print x509.as_text()
                continue

            try:
                trust = constants.TRUST_AUTHENTICITY | constants.TRUST_SERVER
                purpose = cert.certificatePurpose(x509)
                if not (purpose & constants.PURPOSE_CA):
                    trust &= ~constants.TRUST_SERVER
                    log.warn('Importing non-root certificate: %s' % \
                             (commonName))
            except utils.CertificateException:
                log.warn('Could not determine certificate type, assuming "%s": %s' % \
                              (constants.PURPOSE_CA, commonName))
                purpose = constants.PURPOSE_CA
                #print x509.as_text()

            #XXX [i18n] Can a commonName contain non-ascii characters?
            cert.Certificate.update(parcel, itsName,
                displayName = unicode(commonName),
                purpose=purpose,
                trust=trust,
                fingerprintAlgorithm='sha1',
                fingerprint=utils.fingerprint(x509),
                pem=lobType.makeValue(''.join(pem)),
                asText=lobType.makeValue(x509.as_text()),
            )
            pem = []
            certificates += 1
            itsName = None

        elif pem:
            pem.append(line)

        lastLine = line

    log.info(
        'Imported %d certificates from %s in %s',
        certificates, filename, moduleName
    )
    def __init__(self, parent, x509, host, err, size=wx.DefaultSize,
     pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
        """
        Initialize dialog.

        @param x509: The certificate the site returned.
        @param host: The host we think we are connected with.
        @param err:  The verification error code
        """ 

        # Instead of calling wx.Dialog.__init__ we precreate the dialog
        # so we can set an extra style that must be set before
        # creation, and then we create the GUI dialog using the Create
        # method.
        pre = wx.PreDialog()
        pre.Create(parent, -1, _(u'Ignore SSL error?'), pos, size, style)

        # This next step is the most important, it turns this Python
        # object into the real wrapper of the dialog (instead of pre)
        # as far as the wxPython extension is concerned.
        self.this = pre.this

        # Now continue with the normal construction of the dialog
        # contents
        sizer = wx.BoxSizer(wx.VERTICAL)

        # Static text

        try:
            err.upper()
            errString = err
        except AttributeError:
            errString = errors.getCertificateVerifyErrorString(err)
        message = _(u'There was an error with this SSL connection.\nHost: %(host)s.\nThe error was: %(sslError)s.\nIgnoring this error may be dangerous!\nSHA1 fingerprint: %(fingerprint)s') % \
                   {'host': host, 'sslError': errString, 'fingerprint': utils.fingerprint(x509)}
        label = wx.StaticText(self, -1, message)
        sizer.Add(label, 0, wx.ALIGN_LEFT|wx.ALL, 5)

        # multiline readonly edit control
        # XXX [i18n] This cannot be localized. Split into separate fields
        # XXX [i18n] like the certificate detail view.
        text = wx.TextCtrl(self, -1, x509.as_text(), wx.DefaultPosition, 
                           [400,-1], style=wx.TE_MULTILINE|wx.TE_READONLY)
        sizer.Add(text, 1, wx.GROW|wx.ALIGN_CENTRE|wx.ALL, 5)

        # OK, Cancel buttons

        box = wx.BoxSizer(wx.HORIZONTAL)

        btn = wx.Button(self, wx.ID_OK, _(u'Ignore Error'))
        box.Add(btn, 0, wx.ALIGN_RIGHT|wx.ALL, 5)

        btn = wx.Button(self, wx.ID_CANCEL, _(u'Disconnect'))
        btn.SetDefault()
        box.Add(btn, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
        btn.SetFocus()

        sizer.Add(box, 0, wx.ALIGN_RIGHT|wx.ALL, 5)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        sizer.Fit(self)
        self.CenterOnScreen()
    def __init__(self, parent, x509, host, storedUntrusted, size=wx.DefaultSize,
     pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
        """
        Initialize dialog.

        @param x509:            The certificate the site returned.
        @param host:            The host we think we are connected with.
        @param storedUntrusted: The certificate (if any) that is already stored
                                in the repository but is not trusted.
        """ 

        # Instead of calling wx.Dialog.__init__ we precreate the dialog
        # so we can set an extra style that must be set before
        # creation, and then we create the GUI dialog using the Create
        # method.
        pre = wx.PreDialog()
        pre.Create(parent, -1, _(u'Trust site certificate?'), pos, size, style)

        # This next step is the most important, it turns this Python
        # object into the real wrapper of the dialog (instead of pre)
        # as far as the wxPython extension is concerned.
        self.this = pre.this

        # Now continue with the normal construction of the dialog
        # contents
        sizer = wx.BoxSizer(wx.VERTICAL)

        # Static text

        if storedUntrusted is None:
            message = _(u'Host: %(host)s.\nDo you want to trust this certificate?\nSHA1 fingerprint: %(fingerprint)s') % \
                       {'host': host, 'fingerprint': utils.fingerprint(x509)}
        else:
            message = _(u'Host: %(host)s.\nThis certificate is already known but not trusted.\nDo you want to trust this certificate now?\nSHA1 fingerprint: %(fingerprint)s') % \
                       {'host': host, 'fingerprint': utils.fingerprint(x509)}
        label = wx.StaticText(self, -1, message)
        sizer.Add(label, 0, wx.ALIGN_LEFT|wx.ALL, 5)

        # multiline readonly edit control
        # XXX [i18n] This cannot be localized. Split into separate fields
        # XXX [i18n] like the certificate detail view.
        text = wx.TextCtrl(self, -1, x509.as_text(), wx.DefaultPosition, 
                           [400,-1], style=wx.TE_MULTILINE|wx.TE_READONLY)
        sizer.Add(text, 1, wx.GROW|wx.ALIGN_CENTRE|wx.ALL, 5)

        # radio
        
        radiobox = wx.BoxSizer(wx.VERTICAL)
        
        first = True
        rbs = []
        choices=[_(u'Trust the authenticity of this certificate &until you quit Chandler.'),
                 _(u'Trust the authenticity of this certificate &permanently.')]
        for choice in choices:
            if first:
                style = wx.ALIGN_LEFT|wx.RB_GROUP
            else:
                style = wx.ALIGN_LEFT
            rb = wx.RadioButton(self, -1, choice, wx.DefaultPosition, 
                                wx.DefaultSize, style)
            rbs += [rb]
            radiobox.Add(rb, 1, wx.ALIGN_LEFT|wx.ALL, 5)
            
            if first:
                rb.SetValue(True)
                first = False

        sizer.Add(radiobox, 0, wx.ALIGN_LEFT|wx.ALL, 5)

        # OK, Cancel buttons

        box = wx.BoxSizer(wx.HORIZONTAL)

        btn = wx.Button(self, wx.ID_OK)
        box.Add(btn, 0, wx.ALIGN_RIGHT|wx.ALL, 5)

        btn = wx.Button(self, wx.ID_CANCEL)
        btn.SetDefault()
        box.Add(btn, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
        btn.SetFocus()

        sizer.Add(box, 0, wx.ALIGN_RIGHT|wx.ALL, 5)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        sizer.Fit(self)
        self.CenterOnScreen()

        self.rbs = rbs