Exemple #1
0
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()));
}
Exemple #2
0
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 );
	}