CertificateDialog::CertificateDialog(QList<QSslCertificate> certificates, QWidget *parent) : Dialog(parent), m_certificates(certificates), m_ui(new Ui::CertificateDialog) { m_ui->setupUi(this); m_ui->buttonBox->button(QDialogButtonBox::Save)->setText(tr("Export…")); if (certificates.isEmpty()) { setWindowTitle(tr("Invalid Certificate")); return; } setWindowTitle(tr("View Certificate for %1").arg(certificates.first().subjectInfo(QSslCertificate::CommonName).join(QLatin1String(", ")))); QStandardItemModel *chainModel(new QStandardItemModel(this)); QStandardItem *certificateItem(nullptr); for (int i = (certificates.count() - 1); i >= 0; --i) { QStandardItem *parentCertificateItem(certificateItem); certificateItem = new QStandardItem(certificates.at(i).subjectInfo(QSslCertificate::Organization).value(0, tr("Unknown"))); certificateItem->setData(i, Qt::UserRole); if (parentCertificateItem) { parentCertificateItem->appendRow(certificateItem); } else { chainModel->appendRow(certificateItem); } } m_ui->chainItemView->setViewMode(ItemViewWidget::TreeViewMode); m_ui->chainItemView->setModel(chainModel); m_ui->chainItemView->expandAll(); m_ui->chainItemView->setCurrentIndex(chainModel->index(0, 0)); m_ui->detailsItemView->setViewMode(ItemViewWidget::TreeViewMode); m_ui->detailsItemView->setModel(new QStandardItemModel(this)); updateCertificate(); connect(m_ui->chainItemView, SIGNAL(needsActionsUpdate()), this, SLOT(updateCertificate())); connect(m_ui->detailsItemView, SIGNAL(needsActionsUpdate()), this, SLOT(updateValue())); connect(m_ui->buttonBox->button(QDialogButtonBox::Save), SIGNAL(clicked(bool)), this, SLOT(exportCertificate())); }
static int updateCertChain( INOUT PKCS11_INFO *pkcs11Info, IN_HANDLE const CRYPT_CERTIFICATE iCryptCert ) { static const CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; static const CK_CERTIFICATE_TYPE certType = CKC_X_509; CK_ATTRIBUTE certTemplate[] = { { CKA_CLASS, ( CK_VOID_PTR ) &certClass, sizeof( CK_OBJECT_CLASS ) }, { CKA_CERTIFICATE_TYPE, ( CK_VOID_PTR ) &certType, sizeof( CK_CERTIFICATE_TYPE ) }, { CKA_ISSUER, NULL_PTR, 0 }, { CKA_SERIAL_NUMBER, NULL_PTR, 0 }, }; BOOLEAN isLeafCert = TRUE, seenNonDuplicate = FALSE; int value, iterationCount, cryptStatus; assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) ); REQUIRES( isHandleRangeValid( iCryptCert ) ); /* If we've been passed a standalone certificate, check whether it's implicitly trusted, which allows it to be added without requiring the presence of a corresponding public/private key in the device */ cryptStatus = krnlSendMessage( iCryptCert, IMESSAGE_GETATTRIBUTE, &value, CRYPT_CERTINFO_CERTTYPE ); if( cryptStatusError( cryptStatus ) ) { return( ( cryptStatus == CRYPT_ARGERROR_OBJECT ) ? \ CRYPT_ARGERROR_NUM1 : cryptStatus ); } if( value == CRYPT_CERTTYPE_CERTIFICATE ) { cryptStatus = krnlSendMessage( iCryptCert, IMESSAGE_GETATTRIBUTE, &value, CRYPT_CERTINFO_TRUSTED_IMPLICIT ); if( cryptStatusError( cryptStatus ) ) return( CRYPT_ARGERROR_NUM1 ); /* If the certificate is implicitly trusted we indicate that it's (effectively) a non-leaf certificate so that it can be added even if there's no corresponding key already in the device */ if( value ) isLeafCert = FALSE; } /* Add each certificate in the chain to the device */ for( iterationCount = 0; iterationCount < FAILSAFE_ITERATIONS_MED; iterationCount++ ) { CK_OBJECT_HANDLE hObject; DYNBUF iAndSDB; /* If the certificate is already present, don't do anything */ cryptStatus = dynCreate( &iAndSDB, iCryptCert, CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER ); if( cryptStatusError( cryptStatus ) ) return( cryptStatus ); cryptStatus = addIAndSToTemplate( &certTemplate[ 2 ], dynData( iAndSDB ), dynLength( iAndSDB ) ); if( cryptStatusError( cryptStatus ) ) { /* In theory we could simply skip any certificates for which we can't decode the iAndS, but in practice it's probably better to fail and warn the user than to continue with only some certificates added */ dynDestroy( &iAndSDB ); return( cryptStatus ); } cryptStatus = findObject( pkcs11Info, &hObject, certTemplate, 4 ); dynDestroy( &iAndSDB ); if( cryptStatusError( cryptStatus ) ) { /* The certificate isn't already present, write it */ cryptStatus = updateCertificate( pkcs11Info, iCryptCert, isLeafCert ); if( cryptStatusError( cryptStatus ) ) return( cryptStatus ); isLeafCert = FALSE; seenNonDuplicate = TRUE; } /* Try and move to the next certificate */ cryptStatus = krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, MESSAGE_VALUE_CURSORNEXT, CRYPT_CERTINFO_CURRENT_CERTIFICATE ); if( cryptStatusError( cryptStatus ) ) break; } ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED ); return( seenNonDuplicate ? CRYPT_OK : CRYPT_ERROR_DUPLICATE ); }