int main(int argc, char *argv[]) { int ret; /* general return value */ uint32_t keyhandle = 0; /* handle of quote key */ unsigned int pcrmask = 0; /* pcr register mask */ unsigned char passhash1[TPM_HASH_SIZE]; /* hash of key password */ unsigned char nonce[TPM_NONCE_SIZE]; /* nonce data */ STACK_TPM_BUFFER(signature); pubkeydata pubkey; /* public key structure */ unsigned char *passptr; TPM_PCR_COMPOSITE tpc; STACK_TPM_BUFFER (ser_tpc); STACK_TPM_BUFFER (ser_tqi); STACK_TPM_BUFFER (response); uint32_t pcrs; int i; uint16_t sigscheme = TPM_SS_RSASSAPKCS1v15_SHA1; TPM_PCR_SELECTION tps; static char *keypass = NULL; const char *certFilename = NULL; int verbose = FALSE; TPM_setlog(0); /* turn off verbose output from TPM driver */ for (i=1 ; i<argc ; i++) { if (strcmp(argv[i],"-hk") == 0) { i++; if (i < argc) { /* convert key handle from hex */ if (1 != sscanf(argv[i], "%x", &keyhandle)) { printf("Invalid -hk argument '%s'\n",argv[i]); exit(2); } if (keyhandle == 0) { printf("Invalid -hk argument '%s'\n",argv[i]); exit(2); } } else { printf("-hk option needs a value\n"); printUsage(); } } else if (!strcmp(argv[i], "-pwdk")) { i++; if (i < argc) { keypass = argv[i]; } else { printf("Missing parameter to -pwdk\n"); printUsage(); } } else if (strcmp(argv[i],"-bm") == 0) { i++; if (i < argc) { /* convert key handle from hex */ if (1 != sscanf(argv[i], "%x", &pcrmask)) { printf("Invalid -bm argument '%s'\n",argv[i]); exit(2); } } else { printf("-bm option needs a value\n"); printUsage(); } } else if (!strcmp(argv[i], "-cert")) { i++; if (i < argc) { certFilename = argv[i]; } else { printf("Missing parameter to -cert\n"); printUsage(); } } else if (!strcmp(argv[i], "-h")) { printUsage(); } else if (!strcmp(argv[i], "-v")) { verbose = TRUE; TPM_setlog(1); } else { printf("\n%s is not a valid option\n", argv[i]); printUsage(); } } if ((keyhandle == 0) || (pcrmask == 0)) { printf("Missing argument\n"); printUsage(); } /* get the SHA1 hash of the password string for use as the Key Authorization Data */ if (keypass != NULL) { TSS_sha1((unsigned char *)keypass, strlen(keypass), passhash1); passptr = passhash1; } else { passptr = NULL; } /* for testing, use the password hash as the test nonce */ memcpy(nonce, passhash1, TPM_HASH_SIZE); ret = TPM_GetNumPCRRegisters(&pcrs); if (ret != 0) { printf("Error reading number of PCR registers.\n"); exit(-1); } if (pcrs > TPM_NUM_PCR) { printf("Library does not support that many PCRs.\n"); exit(-1); } tps.sizeOfSelect = pcrs / 8; for (i = 0; i < tps.sizeOfSelect; i++) { tps.pcrSelect[i] = (pcrmask & 0xff); pcrmask >>= 8; } /* ** perform the TPM Quote function */ ret = TPM_Quote(keyhandle, /* KEY handle */ passptr, /* Key Password (hashed), or null */ nonce, /* nonce data */ &tps, /* specify PCR registers */ &tpc, /* pointer to pcr composite */ &signature);/* buffer to receive result, int to receive result length */ if (ret != 0) { printf("Error '%s' from TPM_Quote\n", TPM_GetErrMsg(ret)); exit(ret); } /* ** Get the public key and convert to an OpenSSL RSA public key */ ret = TPM_GetPubKey(keyhandle, passptr, &pubkey); if (ret != 0) { printf("quote: Error '%s' from TPM_GetPubKey\n", TPM_GetErrMsg(ret)); exit(-6); } ret = TPM_ValidatePCRCompositeSignature(&tpc, nonce, &pubkey, &signature, sigscheme); if (ret) { printf("Error %s from validating the signature over the PCR composite.\n", TPM_GetErrMsg(ret)); exit(ret); } printf("Verification against AIK succeeded\n"); /* optionally verify the quote signature against the key certificate */ if (certFilename != NULL) { unsigned char *certStream = NULL; /* freed @1 */ uint32_t certStreamLength; X509 *x509Certificate = NULL; /* freed @2 */ unsigned char *tmpPtr; /* because d2i_X509 moves the ptr */ /* AIK public key parts */ RSA *rsaKey = NULL; /* freed @3 */ if (verbose) printf("quote: verifying the signature against the certificate\n"); /* load the key certificate */ if (ret == 0) { ret = TPM_ReadFile(certFilename, &certStream, /* freed @1 */ &certStreamLength); } /* convert to openssl X509 */ if (ret == 0) { if (verbose) printf("quote: parsing the certificate stream\n"); tmpPtr = certStream; x509Certificate = d2i_X509(NULL, (const unsigned char **)&tmpPtr, certStreamLength); if (x509Certificate == NULL) { printf("Error in certificate deserialization d2i_X509()\n"); ret = -1; } } if (ret == 0) { if (verbose) printf("quote: get the certificate public key\n"); ret = GetRSAKey(&rsaKey, /* freed @3 */ x509Certificate); } if (ret == 0) { if (verbose) printf("quote: quote validate signature\n"); ret = TPM_ValidatePCRCompositeSignatureRSA(&tpc, nonce, rsaKey, &signature, sigscheme); if (ret != 0) { printf("Verification against certificate failed\n"); } } if (ret == 0) { printf("Verification against certificate succeeded\n"); } free(certStream); /* @1 */ X509_free(x509Certificate); /* @2 */ RSA_free(rsaKey); /* @3 */ } exit(ret); }
static int sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj) { int r; sc_pkcs15_cert_t *cert = NULL; struct sc_priv_data *priv = NULL; sc_pkcs15_cert_info_t *cinfo = cert_obj->data; X509 *x509 = NULL; EVP_PKEY *pubkey = NULL; u8 *p; char *tmp; debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]); r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); if (r) { logit("Certificate read failed: %s", sc_strerror(r)); goto err; } x509 = X509_new(); if (x509 == NULL) { r = -1; goto err; } p = cert->data; if (!d2i_X509(&x509, &p, cert->data_len)) { logit("Unable to parse X.509 certificate"); r = -1; goto err; } sc_pkcs15_free_certificate(cert); cert = NULL; pubkey = X509_get_pubkey(x509); X509_free(x509); x509 = NULL; if (pubkey->type != EVP_PKEY_RSA) { logit("Public key is of unknown type"); r = -1; goto err; } k->rsa = EVP_PKEY_get1_RSA(pubkey); EVP_PKEY_free(pubkey); k->rsa->flags |= RSA_FLAG_SIGN_VER; RSA_set_method(k->rsa, sc_get_rsa_method()); priv = xmalloc(sizeof(struct sc_priv_data)); priv->cert_id = cinfo->id; priv->ref_count = 1; RSA_set_app_data(k->rsa, priv); k->flags = KEY_FLAG_EXT; tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX); debug("fingerprint %d %s", key_size(k), tmp); xfree(tmp); return 0; err: if (cert) sc_pkcs15_free_certificate(cert); if (pubkey) EVP_PKEY_free(pubkey); if (x509) X509_free(x509); return r; }
static int __pkcs11h_crypto_openssl_certificate_is_issuer ( IN void * const global_data, IN const unsigned char * const issuer_blob, IN const size_t issuer_blob_size, IN const unsigned char * const cert_blob, IN const size_t cert_blob_size ) { X509 *x509_issuer = NULL; X509 *x509_cert = NULL; EVP_PKEY *pub_issuer = NULL; __pkcs11_openssl_d2i_t d2i; PKCS11H_BOOL is_issuer = FALSE; (void)global_data; /*_PKCS11H_ASSERT (global_data!=NULL); NOT NEEDED*/ _PKCS11H_ASSERT (issuer_blob!=NULL); _PKCS11H_ASSERT (cert_blob!=NULL); if ( (x509_issuer = X509_new ()) == NULL || (x509_cert = X509_new ()) == NULL ) { goto cleanup; } d2i = (__pkcs11_openssl_d2i_t)issuer_blob; if ( !d2i_X509 ( &x509_issuer, &d2i, issuer_blob_size ) ) { goto cleanup; } d2i = (__pkcs11_openssl_d2i_t)cert_blob; if ( !d2i_X509 ( &x509_cert, &d2i, cert_blob_size ) ) { goto cleanup; } if ( (pub_issuer = X509_get_pubkey (x509_issuer)) == NULL ) { goto cleanup; } if ( !X509_NAME_cmp ( X509_get_subject_name (x509_issuer), X509_get_issuer_name (x509_cert) ) && X509_verify (x509_cert, pub_issuer) == 1 ) { is_issuer = TRUE; } cleanup: if (pub_issuer != NULL) { EVP_PKEY_free (pub_issuer); pub_issuer = NULL; } if (x509_issuer != NULL) { X509_free (x509_issuer); x509_issuer = NULL; } if (x509_cert != NULL) { X509_free (x509_cert); x509_cert = NULL; } return is_issuer; }
/* returns newly allocated RDSSL_CERT or NULL */ RDSSL_CERT * rdssl_cert_read(uint8 * data, uint32 len) { /* this will move the data pointer but we don't care, we don't use it again */ return d2i_X509(NULL, (D2I_X509_CONST unsigned char **) &data, len); }
// // Load OpenSSL's list of root certificate authorities // void PaymentServer::LoadRootCAs(X509_STORE* _store) { if (PaymentServer::certStore == NULL) atexit(PaymentServer::freeCertStore); else freeCertStore(); // Unit tests mostly use this, to pass in fake root CAs: if (_store) { PaymentServer::certStore = _store; return; } // Normal execution, use either -rootcertificates or system certs: PaymentServer::certStore = X509_STORE_new(); // Note: use "-system-" default here so that users can pass -rootcertificates="" // and get 'I don't like X.509 certificates, don't trust anybody' behavior: QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-")); // Empty store if (certFile.isEmpty()) { qDebug() << QString("PaymentServer::%1: Payment request authentication via X.509 certificates disabled.").arg(__func__); return; } QList<QSslCertificate> certList; if (certFile != "-system-") { qDebug() << QString("PaymentServer::%1: Using \"%2\" as trusted root certificate.").arg(__func__).arg(certFile); certList = QSslCertificate::fromPath(certFile); // Use those certificates when fetching payment requests, too: QSslSocket::setDefaultCaCertificates(certList); } else certList = QSslSocket::systemCaCertificates(); int nRootCerts = 0; const QDateTime currentTime = QDateTime::currentDateTime(); Q_FOREACH (const QSslCertificate& cert, certList) { // Don't log NULL certificates if (cert.isNull()) continue; // Not yet active/valid, or expired certificate if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) { ReportInvalidCertificate(cert); continue; } #if QT_VERSION >= 0x050000 // Blacklisted certificate if (cert.isBlacklisted()) { ReportInvalidCertificate(cert); continue; } #endif QByteArray certData = cert.toDer(); const unsigned char *data = (const unsigned char *)certData.data(); X509* x509 = d2i_X509(0, &data, certData.size()); if (x509 && X509_STORE_add_cert(PaymentServer::certStore, x509)) { // Note: X509_STORE_free will free the X509* objects when // the PaymentServer is destroyed ++nRootCerts; } else { ReportInvalidCertificate(cert); continue; } } qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates"; // Project for another day: // Fetch certificate revocation lists, and add them to certStore. // Issues to consider: // performance (start a thread to fetch in background?) // privacy (fetch through tor/proxy so IP address isn't revealed) // would it be easier to just use a compiled-in blacklist? // or use Qt's blacklist? // "certificate stapling" with server-side caching is more efficient }
CK_RV PKCS11_Objects_OpenSSL::FindObjects(Cryptoki_Session_Context* pSessionCtx, CK_OBJECT_HANDLE_PTR phObjects, CK_ULONG ulMaxCount, CK_ULONG_PTR pulObjectCount) { FIND_OBJECT_DATA *pData = (FIND_OBJECT_DATA*)pSessionCtx->FindObjectsCtx; UINT32 cntObj = 0; *pulObjectCount = 0; if(pData == NULL) return CKR_FUNCTION_FAILED; if(ulMaxCount == 0) return CKR_ARGUMENTS_BAD; { FileEnumCtx ctx; CHAR fileName[20]; if(g_OpenSSL_Token.Storage == NULL || g_OpenSSL_Token.Storage->GetFileEnum == NULL) { return CKR_FUNCTION_NOT_SUPPORTED; } if(!g_OpenSSL_Token.Storage->GetFileEnum(pData->GroupName, pData->ObjectType, ctx)) return CKR_FUNCTION_FAILED; while(g_OpenSSL_Token.Storage->GetNextFile(ctx, fileName, ARRAYSIZE(fileName))) { UINT32 dataLen = 0; if(g_OpenSSL_Token.Storage->Read(fileName, pData->GroupName, pData->ObjectType, NULL, dataLen)) { UINT8* pObj = (UINT8*)TINYCLR_SSL_MALLOC(dataLen); if(pObj) { g_OpenSSL_Token.Storage->Read(fileName, pData->GroupName, pData->ObjectType, pObj, dataLen); switch(pData->ObjectType) { case CertificateType: { OBJECT_DATA *pObject = NULL; const UINT8* pTmp = pObj; CK_OBJECT_HANDLE hObjTmp, *pObjHandle; X509* x509 = d2i_X509(NULL, &pTmp, dataLen); if(x509 == NULL) { TINYCLR_SSL_FREE(pObj); return CKR_FUNCTION_FAILED; } if(phObjects == NULL) { pObjHandle = &hObjTmp; } else { pObjHandle = &phObjects[cntObj]; } if(CKR_OK != LoadX509Cert(pSessionCtx, x509, &pObject, NULL, pObjHandle)) { X509_free(x509); TINYCLR_SSL_FREE(pObj); //return CKR_FUNCTION_FAILED; g_OpenSSL_Token.Storage->Delete( fileName, pData->GroupName ); continue; } hal_strcpy_s(pObject->GroupName, ARRAYSIZE(pObject->GroupName), pData->GroupName); hal_strcpy_s(pObject->FileName , ARRAYSIZE(pObject->FileName ), fileName ); cntObj++; TINYCLR_SSL_FREE(pObj); if(cntObj >= ulMaxCount) { *pulObjectCount = cntObj; return CKR_OK; } } break; case KeyType: { // TODO: TINYCLR_SSL_FREE(pObj); } break; default: // TODO: TINYCLR_SSL_FREE(pObj); break; } } } } } *pulObjectCount = cntObj; return CKR_OK; }
XSECCryptoKey * InteropResolver::resolveKey(DSIGKeyInfoList * lst) { // First check if this has an X509 cert + an X509 CRL const XMLCh * b64cert = NULL; const XMLCh * b64crl = NULL; int lstSize = (int) lst->getSize(); for (int i = 0; i < lstSize; ++i) { DSIGKeyInfo * ki; ki = lst->item(i); const XMLCh * rawuri; if (ki->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) { DSIGKeyInfoX509 * kix509 = static_cast<DSIGKeyInfoX509 *>(ki); if ((rawuri = kix509->getRawRetrievalURI()) != NULL) { // We have a raw certificate by de-reference // Assume it is just a file dereference and open the cert return openCertURI(rawuri); } if (kix509->getCertificateListSize() == 1) { b64cert = kix509->getCertificateItem(0); } if (b64crl == NULL) { b64crl = kix509->getX509CRL(); } } else if (ki->getKeyInfoType() == DSIGKeyInfo::KEYINFO_NAME) { DSIGKeyInfoName * kn = static_cast<DSIGKeyInfoName *>(ki); if (kn->getKeyName() != NULL) { static XMLCh certStr[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_c, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_r, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_t, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_s, XERCES_CPP_NAMESPACE_QUALIFIER chForwardSlash, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; static XMLCh extStr[] = { XERCES_CPP_NAMESPACE_QUALIFIER chPeriod, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_c, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_r, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_t, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; safeBuffer fname; fname = certStr; fname.sbXMLChCat(kn->getKeyName()); fname.sbXMLChCat(extStr); fname.sbStrlwr(); return openCertURI(fname.rawXMLChBuffer()); } } } if (b64cert != NULL && b64crl != NULL) { // We have a certificate and a crl, lets get the cert and check in the crl OpenSSLCryptoBase64 b64; char * transb64cert = XMLString::transcode(b64cert); unsigned char * x509buf = new unsigned char[strlen(transb64cert)]; ArrayJanitor<unsigned char> j_x509buf(x509buf); int x509bufLen; X509 *x; b64.decodeInit(); x509bufLen = b64.decode((unsigned char *) transb64cert, (unsigned int) strlen(transb64cert), x509buf, (unsigned int) strlen(transb64cert)); x509bufLen += b64.decodeFinish(&x509buf[x509bufLen], (unsigned int) strlen(transb64cert) - x509bufLen); XSEC_RELEASE_XMLCH(transb64cert); if (x509bufLen > 0) { #if defined(XSEC_OPENSSL_D2IX509_CONST_BUFFER) x = d2i_X509(NULL, (const unsigned char **) (&x509buf), x509bufLen ); #else x = d2i_X509(NULL, &x509buf, x509bufLen); #endif } else return NULL; // Something has gone wrong if (x == NULL) return NULL; // Now the CRL char * transb64crl = XMLString::transcode(b64crl); unsigned char * crlbuf = new unsigned char[strlen(transb64crl)]; ArrayJanitor<unsigned char> j_crlbuf(crlbuf); int crlbufLen; X509_CRL * c; b64.decodeInit(); crlbufLen = b64.decode((unsigned char*) transb64crl, (unsigned int) strlen(transb64crl), crlbuf, (unsigned int) strlen(transb64crl)); crlbufLen += b64.decodeFinish(&crlbuf[crlbufLen], (unsigned int) strlen(transb64crl) - crlbufLen); XSEC_RELEASE_XMLCH(transb64crl); if (crlbufLen > 0) { #if defined(XSEC_OPENSSL_D2IX509_CONST_BUFFER) c = d2i_X509_CRL(NULL, (const unsigned char **) (&crlbuf), crlbufLen); #else c = d2i_X509_CRL(NULL, &crlbuf, crlbufLen); #endif } else return NULL; // Something has gone wrong if (c == NULL) return NULL; // Now check if the cert is in the CRL (code lifted from OpenSSL x509_vfy.c int idx; X509_REVOKED rtmp; /* Look for serial number of certificate in CRL */ rtmp.serialNumber = X509_get_serialNumber(x); idx = sk_X509_REVOKED_find(c->crl->revoked, &rtmp); /* Not found: OK */ if(idx != -1) { std::cerr << "Warning - certificate revoked in attached CRL" << std::endl; } OpenSSLCryptoX509 ox(x); X509_free(x); X509_CRL_free(c); return ox.clonePublicKey(); } // Do a run through each match in the directory while (m_searchFinished == false) { X509 * x = nextFile2Cert(); if (x != NULL) { if (checkMatch(lst, x)) { OpenSSLCryptoX509 ox(x); X509_free(x); return ox.clonePublicKey(); } } X509_free(x); } return false; }
/* * Check for: * - cert identity matching domain name * - cert is within validity perios * - digital sig is valid */ verifyOvCertificate(ovStruct_t *ovP) { uchar *buff, *subj, *issuer; int version; const uchar *ptr, *tmpPtr; const uchar *data; size_t len, msgLen, totalCertLen, serverCertLen; size_t parsedLen = 0; size_t verifyCertLen; int count = 0; #define CERT_LEN_INDEX 1 // buff[0] points to Handshake Type - certificate buff = ovP->certBuff; len = ovP->certLen; msgLen = GET_BE16(&buff[CERT_LEN_INDEX+1]); totalCertLen = GET_BE16(&buff[CERT_LEN_INDEX+1+3]); serverCertLen = GET_BE16(&buff[CERT_LEN_INDEX+1+3+3]); log_info(fp, "\n Pkg Len = %d, Total Cert Len = %d", msgLen, totalCertLen); log_info(fp, "\n Server Certificate verification, Len: %d", serverCertLen); // Parse the Server Cert ptr = &buff[10]; X509 *cert = d2i_X509(NULL, &ptr, serverCertLen); if (cert == NULL) { log_info(fp, "\n d2i_X509 returns NULL for Cert verification"); return -1; } log_info(fp, "\n.........Server Certificate........................"); subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); version = ((int)X509_get_version(cert)) + 1; // 0 indexed log_info(fp, "\nSubject: %s, \nIssuer: %s, \n Version: %d", subj, issuer, version); // Get Public Key Algorith Name int pkey = OBJ_obj2nid(cert->cert_info->key->algor->algorithm); if (pkey == NID_undef) { log_info (fp, "\n Cert Verify: unable to find signature algo"); goto clean; } char sigalgo[100]; const char * sslbuf = OBJ_nid2ln(pkey); if (strlen(sslbuf) > 100) { log_info (fp, "\n Cert Verify: len is greater than allocated"); goto clean; } strncpy(sigalgo, sslbuf, 100); log_info(fp, ", Public Key Algorithm Algorithm: %s", sigalgo); EVP_PKEY *public_key = X509_get_pubkey(cert); if (pkey == NID_rsaEncryption) { if (public_key == NULL) { log_info(fp, "\nunable to get public key from certificate"); return -1; } char *rsa_e_dec, *rsa_n_hex; ovP->rsa_key = public_key->pkey.rsa; // Both the following are printable strings and need to be freed // by caling OPENSSL_free() rsa_e_dec = BN_bn2dec(ovP->rsa_key->e); // RSA Exponent rsa_n_hex = BN_bn2hex(ovP->rsa_key->n); // RSA Modulus log_info(fp, "\n RSA Exponent = %s, \n RSA Modulus = %s", rsa_e_dec, rsa_n_hex); } EVP_PKEY_free(public_key); clean: OPENSSL_free(subj); OPENSSL_free(issuer); // Parse the Server Cert Chain ptr = &buff[10+serverCertLen]; // Set ptr to point to next Cert Len field parsedLen = serverCertLen+3; tmpPtr = ptr+3; while (parsedLen < totalCertLen) { log_info(fp, "\n.........Server Certificate Chain %d.............", count++); //printf("\n Len: Parsed: %d, Total: %d", parsedLen, totalCertLen); verifyCertLen = GET_BE16(&ptr[1]); log_info(fp, "\nCert Chain Len: %d", verifyCertLen); X509 *cert = d2i_X509(NULL, &tmpPtr, serverCertLen); if (cert == NULL) { log_info(fp, "\n d2i_X509 returns NULL for Cert verification chain"); return -1; } subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); log_info(fp, "\nSubject: %s", subj); OPENSSL_free(subj); ptr += verifyCertLen + 3; // Set ptr to point to next Cert Len field tmpPtr = ptr+3; parsedLen += verifyCertLen+3; } // End parsing Cert Chain log_info(fp, "\n.................................................."); }
int EstEID_loadCertInfoEntries(EstEID_Certs *certs, int index) { EstEID_Map cert = certs->certs[index]; CK_SLOT_ID slotID = certs->slotIDs[index]; CK_SESSION_HANDLE session; FAIL_IF(EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))); CK_OBJECT_CLASS objectClass = CKO_CERTIFICATE; CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)}; if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) return FAILURE; CK_OBJECT_HANDLE objectHandle; CK_ULONG objectCount; if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, &objectHandle, 1, &objectCount))) return FAILURE; if (objectCount == 0) return SUCCESS; CK_ATTRIBUTE attribute = {CKA_VALUE, NULL_PTR, 0}; if (EstEID_CK_failure("C_GetAttributeValue", fl->C_GetAttributeValue(session, objectHandle, &attribute, 1))) return FAILURE; CK_ULONG certificateLength = attribute.ulValueLen; CK_BYTE_PTR certificate = (CK_BYTE_PTR)malloc(certificateLength); attribute.pValue = certificate; if (EstEID_CK_failure("C_GetAttributeValue", fl->C_GetAttributeValue(session, objectHandle, &attribute, 1))) return FAILURE; EstEID_mapPutNoAlloc(cert, strdup("certificateAsHex"), EstEID_bin2hex((char *)certificate, certificateLength)); const unsigned char *p = certificate; X509 *x509 = d2i_X509(NULL, &p, certificateLength); char *certMD5; certMD5 = EstEID_getCertHash((char*)certificate); FAIL_IF(EstEID_md5_failure(certMD5)); EstEID_mapPutNoAlloc(cert, strdup("certHash"), certMD5); free(certificate); // todo: error handling of all openssl functions EstEID_mapPutNoAlloc(cert, strdup("validTo"), EstEID_ASN1_TIME_toString(X509_get_notAfter(x509))); EstEID_mapPutNoAlloc(cert, strdup("validFrom"), EstEID_ASN1_TIME_toString(X509_get_notBefore(x509))); unsigned long keyUsage; ASN1_BIT_STRING *usage = (ASN1_BIT_STRING *)X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL); if (usage->length > 0) keyUsage = usage->data[0]; ASN1_BIT_STRING_free(usage); if (keyUsage & X509v3_KU_DIGITAL_SIGNATURE) EstEID_mapPut(cert, "usageDigitalSignature", "TRUE"); if (keyUsage & X509v3_KU_NON_REPUDIATION) { EstEID_mapPut(cert, "usageNonRepudiation", "TRUE"); EstEID_mapPut(cert, "keyUsage", "Non-Repudiation"); // for compatibility with older plugin } EstEID_loadCertEntries(cert, "", X509_get_subject_name(x509)); char *certSerialNumber = (char*)malloc(33); snprintf(certSerialNumber, 32, "%lX", ASN1_INTEGER_get(X509_get_serialNumber(x509))); EstEID_mapPutNoAlloc(cert, strdup("certSerialNumber"), certSerialNumber); EstEID_loadCertEntries(cert, "issuer.", X509_get_issuer_name(x509)); BIO *bio = BIO_new(BIO_s_mem()); if (!PEM_write_bio_X509(bio, x509)) printf("Cannot create PEM\n"); char *b; int len = BIO_get_mem_data(bio, &b); char *pem = (char *)malloc(len + 1); strncpy(pem, b, len); pem[len] = 0; BIO_free(bio); EstEID_mapPutNoAlloc(cert, strdup("certificateAsPEM"), pem); FAIL_IF(EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))); return SUCCESS; }
/* Helper function to trace the signing cert to a trusted CA root * in the OpenSSL Trust Store. */ static int checkCertOpenSSL(const GTPublicationsFile *publications_file) { int res = GT_UNKNOWN_ERROR; unsigned char *cert_der = NULL; size_t cert_der_len; unsigned char *cert_tmp; X509 *cert = NULL; X509_STORE_CTX *store_ctx = NULL; X509_NAME *subj = NULL; ASN1_OBJECT *oid = NULL; char tmp_name[256]; int rc; res = GTPublicationsFile_getSigningCert(publications_file, &cert_der, &cert_der_len); if (res != GT_OK) { goto cleanup; } /* Note that d2i_X509() spoils the pointer to the buffer, use a temporary copy. */ cert_tmp = cert_der; cert = d2i_X509(NULL, (const unsigned char **) &cert_tmp, cert_der_len); if (cert == NULL) { res = GT_NOT_VALID_PUBLICATION; goto cleanup; } #ifdef MAGIC_EMAIL subj = X509_get_subject_name(cert); if (subj == NULL) { res = GT_CRYPTO_FAILURE; goto cleanup; } oid = OBJ_txt2obj("1.2.840.113549.1.9.1", 1); if (oid == NULL) { res = GT_OUT_OF_MEMORY; goto cleanup; } rc = X509_NAME_get_text_by_OBJ(subj, oid, tmp_name, sizeof(tmp_name)); if (rc < 0) { res = GT_INVALID_SIGNATURE; goto cleanup; } if (strcmp(tmp_name, MAGIC_EMAIL) != 0) { res = GT_INVALID_SIGNATURE; goto cleanup; } #endif store_ctx = X509_STORE_CTX_new(); if (store_ctx == NULL) { res = GT_OUT_OF_MEMORY; goto cleanup; } /* The truststore is not initialized by default. */ if (GT_truststore == NULL) { res = GTTruststore_init(1); if (res != GT_OK) goto cleanup; } if (!X509_STORE_CTX_init(store_ctx, GT_truststore, cert, publications_file->signature->d.sign->cert)) { res = GT_OUT_OF_MEMORY; goto cleanup; } rc = X509_verify_cert(store_ctx); if (rc < 0) { res = GT_CRYPTO_FAILURE; goto cleanup; } if (rc != 1) { res = GT_CERT_NOT_TRUSTED; goto cleanup; } res = GT_OK; cleanup: GT_free(cert_der); /* Do not free subj, it points into cert. */ ASN1_OBJECT_free(oid); if (cert != NULL) { X509_free(cert); } if (store_ctx != NULL) { X509_STORE_CTX_free(store_ctx); } return res; }
int certproc(int netsock, int filesock) { char *csr, *chain, *url; unsigned char *csrcp, *chaincp; size_t csrsz, chainsz; int i, rc, idx, cc; enum certop op; long lval; X509 *x, *chainx; X509_EXTENSION *ext; X509V3_EXT_METHOD *method; void *entries; STACK_OF(CONF_VALUE) *val; CONF_VALUE *nval; ext = NULL; idx = -1; method = NULL; chain = csr = url = NULL; rc = 0; x = chainx = NULL; /* File-system and sandbox jailing. */ if ( ! sandbox_before()) goto out; ERR_load_crypto_strings(); if ( ! dropfs(PATH_VAR_EMPTY)) goto out; else if ( ! dropprivs()) goto out; else if ( ! sandbox_after()) goto out; /* Read what the netproc wants us to do. */ op = CERT__MAX; if (0 == (lval = readop(netsock, COMM_CSR_OP))) op = CERT_STOP; else if (CERT_REVOKE == lval || CERT_UPDATE == lval) op = lval; if (CERT_STOP == op) { rc = 1; goto out; } else if (CERT__MAX == op) { warnx("unknown operation from netproc"); goto out; } /* * Pass revocation right through to fileproc. * If the reader is terminated, ignore it. */ if (CERT_REVOKE == op) { if (writeop(filesock, COMM_CHAIN_OP, FILE_REMOVE) >= 0) rc = 1; goto out; } /* * Wait until we receive the DER encoded (signed) certificate * from the network process. * Then convert the DER encoding into an X509 certificate. */ if (NULL == (csr = readbuf(netsock, COMM_CSR, &csrsz))) goto out; csrcp = (u_char *)csr; x = d2i_X509(NULL, (const u_char **)&csrcp, csrsz); if (NULL == x) { warnx("d2i_X509"); goto out; } /* * Extract the CA Issuers from its NID. * TODO: I have no idea what I'm doing. */ idx = X509_get_ext_by_NID(x, NID_info_access, idx); if (idx >= 0 && NULL != (ext = X509_get_ext(x, idx))) method = (X509V3_EXT_METHOD *)X509V3_EXT_get(ext); entries = X509_get_ext_d2i(x, NID_info_access, 0, 0); if (NULL != method && NULL != entries) { val = method->i2v(method, entries, 0); for (i = 0; i < sk_CONF_VALUE_num(val); i++) { nval = sk_CONF_VALUE_value(val, i); if (strcmp(nval->name, "CA Issuers - URI")) continue; url = strdup(nval->value); if (NULL == url) { warn("strdup"); goto out; } break; } } if (NULL == url) { warnx("no CA issuer registered with certificate"); goto out; } /* Write the CA issuer to the netsock. */ if (writestr(netsock, COMM_ISSUER, url) <= 0) goto out; /* Read the full-chain back from the netsock. */ if (NULL == (chain = readbuf(netsock, COMM_CHAIN, &chainsz))) goto out; /* * Then check if the chain is PEM-encoded by looking to see if * it begins with the PEM marker. * If so, ship it as-is; otherwise, convert to a PEM encoded * buffer and ship that. * FIXME: if PEM, re-parse it. */ if (chainsz <= strlen(MARKER) || strncmp(chain, MARKER, strlen(MARKER))) { chaincp = (u_char *)chain; chainx = d2i_X509(NULL, (const u_char **)&chaincp, chainsz); if (NULL == chainx) { warnx("d2i_X509"); goto out; } free(chain); if (NULL == (chain = x509buf(chainx, &chainsz))) goto out; } /* Allow reader termination to just push us out. */ if (0 == (cc = writeop(filesock, COMM_CHAIN_OP, FILE_CREATE))) rc = 1; if (cc <= 0) goto out; if (0 == (cc = writebuf(filesock, COMM_CHAIN, chain, chainsz))) rc = 1; if (cc <= 0) goto out; /* * Next, convert the X509 to a buffer and send that. * Reader failure doesn't change anything. */ free(chain); if (NULL == (chain = x509buf(x, &chainsz))) goto out; if (writebuf(filesock, COMM_CSR, chain, chainsz) < 0) goto out; rc = 1; out: close(netsock); close(filesock); if (NULL != x) X509_free(x); if (NULL != chainx) X509_free(chainx); free(csr); free(url); free(chain); ERR_print_errors_fp(stderr); ERR_free_strings(); return(rc); }
static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret) { PKCS11_TOKEN_private *tpriv; PKCS11_CERT_private *kpriv; PKCS11_CERT *cert, *tmp; char label[256], data[4096]; unsigned char id[256]; CK_CERTIFICATE_TYPE cert_type; size_t size; (void)ctx; (void)session; size = sizeof(cert_type); if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, &cert_type, &size)) return -1; /* Ignore any certs we don't understand */ if (cert_type != CKC_X_509) return 0; tpriv = PRIVTOKEN(token); tmp = (PKCS11_CERT *) OPENSSL_realloc(tpriv->certs, (tpriv->ncerts + 1) * sizeof(PKCS11_CERT)); if (!tmp) { free(tpriv->certs); tpriv->certs = NULL; return -1; } tpriv->certs = tmp; cert = tpriv->certs + tpriv->ncerts++; memset(cert, 0, sizeof(*cert)); cert->_private = kpriv = PKCS11_NEW(PKCS11_CERT_private); kpriv->object = obj; kpriv->parent = token; if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label))) cert->label = BUF_strdup(label); size = sizeof(data); if (!pkcs11_getattr_var(token, obj, CKA_VALUE, data, &size)) { const unsigned char *p = (unsigned char *) data; cert->x509 = d2i_X509(NULL, &p, size); } cert->id_len = sizeof(id); if (!pkcs11_getattr_var(token, obj, CKA_ID, id, &cert->id_len)) { cert->id = (unsigned char *) malloc(cert->id_len); memcpy(cert->id, id, cert->id_len); } /* Initialize internal information */ kpriv->id_len = sizeof(kpriv->id); if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len)) kpriv->id_len = 0; if (ret) *ret = cert; return 0; }
gpg_err_code_t keyutil_get_cert_mpi ( unsigned char *der, size_t len, gcry_mpi_t *p_n_mpi, gcry_mpi_t *p_e_mpi ) { gpg_err_code_t error = GPG_ERR_GENERAL; gcry_mpi_t n_mpi = NULL; gcry_mpi_t e_mpi = NULL; #if defined(ENABLE_GNUTLS) gnutls_x509_crt_t cert = NULL; gnutls_datum_t datum = {der, len}; gnutls_datum_t m = {NULL, 0}, e = {NULL, 0}; #elif defined(ENABLE_OPENSSL) X509 *x509 = NULL; EVP_PKEY *pubkey = NULL; char *n_hex = NULL, *e_hex = NULL; #endif *p_n_mpi = NULL; *p_e_mpi = NULL; #if defined(ENABLE_GNUTLS) if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS) { cert = NULL; error = GPG_ERR_ENOMEM; goto cleanup; } if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) != GNUTLS_E_SUCCESS) { error = GPG_ERR_BAD_CERT; goto cleanup; } if (gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e) != GNUTLS_E_SUCCESS) { error = GPG_ERR_BAD_KEY; m.data = NULL; e.data = NULL; goto cleanup; } if ( gcry_mpi_scan(&n_mpi, GCRYMPI_FMT_USG, m.data, m.size, NULL) || gcry_mpi_scan(&e_mpi, GCRYMPI_FMT_USG, e.data, e.size, NULL) ) { error = GPG_ERR_BAD_KEY; goto cleanup; } #elif defined(ENABLE_OPENSSL) if (!d2i_X509 (&x509, (my_openssl_d2i_t *)&der, len)) { error = GPG_ERR_BAD_CERT; goto cleanup; } if ((pubkey = X509_get_pubkey (x509)) == NULL) { error = GPG_ERR_BAD_CERT; goto cleanup; } if (pubkey->type != EVP_PKEY_RSA) { error = GPG_ERR_WRONG_PUBKEY_ALGO; goto cleanup; } n_hex = BN_bn2hex (pubkey->pkey.rsa->n); e_hex = BN_bn2hex (pubkey->pkey.rsa->e); if(n_hex == NULL || e_hex == NULL) { error = GPG_ERR_BAD_KEY; goto cleanup; } if ( gcry_mpi_scan (&n_mpi, GCRYMPI_FMT_HEX, n_hex, 0, NULL) || gcry_mpi_scan (&e_mpi, GCRYMPI_FMT_HEX, e_hex, 0, NULL) ) { error = GPG_ERR_BAD_KEY; goto cleanup; } #else #error Invalid configuration. #endif *p_n_mpi = n_mpi; n_mpi = NULL; *p_e_mpi = e_mpi; e_mpi = NULL; error = GPG_ERR_NO_ERROR; cleanup: if (n_mpi != NULL) { gcry_mpi_release (n_mpi); n_mpi = NULL; } if (e_mpi != NULL) { gcry_mpi_release (e_mpi); e_mpi = NULL; } #if defined(ENABLE_GNUTLS) if (m.data != NULL) { gnutls_free (m.data); m.data = NULL; } if (e.data != NULL) { gnutls_free (e.data); e.data = NULL; } if (cert != NULL) { gnutls_x509_crt_deinit (cert); cert = NULL; } #elif defined(ENABLE_OPENSSL) if (x509 != NULL) { X509_free (x509); x509 = NULL; } if (pubkey != NULL) { EVP_PKEY_free(pubkey); pubkey = NULL; } if (n_hex != NULL) { OPENSSL_free (n_hex); n_hex = NULL; } if (e_hex != NULL) { OPENSSL_free (e_hex); e_hex = NULL; } #else #error Invalid configuration. #endif return error; }
int dane_verify_cb(int ok, X509_STORE_CTX *store) { struct ub_result *dns_result; struct ub_ctx* ctx; char dns_name[256]; X509 *cert; SSL *con; typedef struct { int verbose_mode; int verify_depth; int always_continue; } mydata_t; int mydata_index; mydata_t *mydata; int retval, err, depth; if (b_err == NULL) b_err=BIO_new_fp(stderr,BIO_NOCLOSE); cert = X509_STORE_CTX_get_current_cert(store); err = X509_STORE_CTX_get_error(store); depth = X509_STORE_CTX_get_error_depth(ctx); int ssl_idx = SSL_get_ex_data_X509_STORE_CTX_idx(); if (ssl_idx < 0) { BIO_printf(b_err, "DANE failed to find SSL index: %d\n", ssl_idx); return -1; } con = X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()); mydata = SSL_get_ex_data(con, mydata_index); int peerfd; peerfd = SSL_get_fd(con); socklen_t len; struct sockaddr_storage addr; char ipstr[INET6_ADDRSTRLEN]; char node[NI_MAXHOST]; int port; len = sizeof addr; getpeername(peerfd, (struct sockaddr*)&addr, &len); // deal with both IPv4 and IPv6: if (addr.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&addr; port = ntohs(s->sin_port); inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); struct sockaddr_in sa; sa.sin_family = AF_INET; inet_pton(AF_INET, ipstr, &sa.sin_addr); int res = getnameinfo((struct sockaddr*)&sa, sizeof(sa), node, sizeof(node), NULL, 0, 0); } else { // AF_INET6 struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; port = ntohs(s->sin6_port); inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); } BIO_printf(b_err, "Peer IP address: %s\n", ipstr); BIO_printf(b_err, "Peer port : %d\n", port); BIO_printf(b_err, "Peer hostname : %s\n", node); ctx = ub_ctx_create(); if(!ctx) { printf("error: could not create unbound context\n"); return -1; } if( (retval=ub_ctx_resolvconf(ctx, "/etc/resolv.conf")) != 0) { printf("error reading resolv.conf: %s. errno says: %s\n", ub_strerror(retval), strerror(errno)); return -1; } if( (retval=ub_ctx_hosts(ctx, "/etc/hosts")) != 0) { printf("error reading hosts: %s. errno says: %s\n", ub_strerror(retval), strerror(errno)); return -1; } retval = sprintf(dns_name, "_%d._tcp.%s", port, node); if(retval < 0) { printf("failure to create dns name\n"); return -1; } BIO_printf(b_err,"DANE dane_verify_cb() dns name: %s\n", dns_name); retval = ub_resolve(ctx, dns_name, 65534, 1, &dns_result); if(retval != 0) { BIO_printf(b_err, "resolve error: %s\n", ub_strerror(retval)); return -1; } if(dns_result->havedata) { int i; for (i = 0; dns_result->data[i] != NULL; i++) { unsigned char usage, selector, matching_type; unsigned char *tlsa_bytes; if (dns_result->len[i] < 35) { // must have at least 1+1+1+32 bytes for the SHA-256 case BIO_printf(b_err, "DANE: Not enough data: %d available\n", dns_result->len[i]); return -1; } unsigned char *rdata = (unsigned char *)dns_result->data[i]; usage = (char) *rdata++; selector = (char) *rdata++; matching_type = (char) *rdata++; tlsa_bytes = (unsigned char *) rdata; X509 *tlsa_cert; tlsa_cert = d2i_X509(NULL, &tlsa_bytes, dns_result->len[i]-3); BIO_printf(b_err, "DANE: Usage %d Selector %d Matching Type %d\n", usage, selector, matching_type); if (selector != 0) continue; if (matching_type != 0) continue; if (usage == 0 || usage == 2) { int retval; retval = ca_constraint(con, tlsa_cert, usage); if (retval == 0) BIO_printf(b_err, "DANE dane_verify_cb() Passed validation for usage %d\n", usage); else BIO_printf(b_err, "DANE dane_verify_cb() Failed validation for usage %d\n", usage); return retval; } if (usage == 1) { int retval; retval = service_cert_constraint(cert, tlsa_cert); if (retval == 0) BIO_printf(b_err, "DANE dane_verify_cb() Passed validation for usage %d\n", usage); else BIO_printf(b_err, "DANE dane_verify_cb() Failed validation for usage %d\n", usage); return retval; } } } return ok; }
int main (int ac, char **av) { FILE *f_in; FILE *f_out; UINT32 proofLen; BYTE *proof; BYTE *pub; UINT32 pubLen; BYTE *certs; UINT32 certsLen; UINT32 certLen; BYTE key[128/8]; BYTE iv[16]; BYTE asymPlain[8 + sizeof(key) + SHA_DIGEST_LENGTH]; unsigned char oaepPad[4] = "TCPA"; BYTE *asymPadded; UINT32 asymPaddedLength; BYTE *asymEnc; UINT32 asymEncLength; BYTE *chal; UINT32 chalLen; BYTE *symEnc; UINT32 symEncLength; BYTE *symAttest; UINT32 symAttestLength; EVP_CIPHER_CTX ctx; X509 *ekX509; X509_NAME *ekSubj; EVP_PKEY *ekPkey; RSA *ekRsa; RSA *aikRsa; UINT32 tt[1]; int trousersIVMode = 1; int out1, out2; int nCerts; int result; if (ac != 5) { fprintf (stderr, "Usage: %s secretfile aikprooffile outchallengefile outrsafile\n", av[0]); exit (1); } /* Read challenge */ if ((f_in = fopen (av[1], "rb")) == NULL) { fprintf (stderr, "Unable to open file %s\n", av[1]); exit (1); } fseek (f_in, 0, SEEK_END); chalLen = ftell (f_in); fseek (f_in, 0, SEEK_SET); chal = malloc (chalLen); if (fread (chal, 1, chalLen, f_in) != chalLen) { fprintf (stderr, "Unable to read file %s\n", av[1]); exit (1); } fclose (f_in); /* Read AIK proof */ if ((f_in = fopen (av[2], "rb")) == NULL) { fprintf (stderr, "Unable to open file %s\n", av[2]); exit (1); } fseek (f_in, 0, SEEK_END); proofLen = ftell (f_in); fseek (f_in, 0, SEEK_SET); proof = malloc (proofLen); if (fread (proof, 1, proofLen, f_in) != proofLen) { fprintf (stderr, "Unable to read file %s\n", av[2]); exit (1); } fclose (f_in); if (proofLen < 3) goto badproof; pubLen = ntohl (*(UINT32*)proof); if (pubLen + 4 + 4 > proofLen) goto badproof; pub = proof + 4; proof += pubLen+4; proofLen -= pubLen+4; certsLen = ntohl (*(UINT32*)proof); if (certsLen + 4 != proofLen) goto badproof; proof += 4; certs = proof; nCerts = 0; for ( ; ; ) { ++nCerts; if (certsLen < 3) goto badproof; certLen = (proof[0]<<16) | (proof[1]<<8) | proof[2]; if (certLen + 3 > certsLen) goto badproof; proof += certLen + 3; certsLen -= certLen + 3; if (certsLen == 0) break; } if (verifyCertChain (trustedRoot, sizeof(trustedRoot), nCerts, certs) != 0) { fprintf (stderr, "Unable to validate certificate chain in proof file\n"); exit (1); } /* Pull endorsement key from 1st cert */ certLen = (certs[0]<<16) | (certs[1]<<8) | certs[2]; certs += 3; if ((ekX509 = d2i_X509 (NULL, (unsigned char const **)&certs, certLen)) == NULL) goto badproof; /* One last check: EK certs must have empty subject fields */ if ((ekSubj = X509_get_subject_name (ekX509)) == NULL) goto badproof; if (X509_NAME_entry_count (ekSubj) != 0) goto badproof; /* OpenSSL can't parse EK key due to OAEP OID - fix it */ { X509_PUBKEY *pk = X509_get_X509_PUBKEY(ekX509); int algbufLen = i2d_X509_ALGOR(pk->algor, NULL); unsigned char *algbuf = malloc(algbufLen); unsigned char *algbufPtr = algbuf; i2d_X509_ALGOR(pk->algor, &algbufPtr); if (algbuf[12] == 7) algbuf[12] = 1; algbufPtr = algbuf; d2i_X509_ALGOR(&pk->algor, (void *)&algbufPtr, algbufLen); free (algbuf); } if ((ekPkey = X509_get_pubkey (ekX509)) == NULL) goto badproof; if ((ekRsa = EVP_PKEY_get1_RSA (ekPkey)) == NULL) goto badproof; /* Construct encrypted output challenge */ RAND_bytes (key, sizeof(key)); RAND_bytes (iv, sizeof(iv)); /* Prepare buffer to be RSA encrypted to endorsement key */ ((UINT32 *)asymPlain)[0] = htonl(TPM_ALG_AES); ((UINT16 *)asymPlain)[2] = htons(TPM_ES_SYM_CBC_PKCS5PAD); ((UINT16 *)asymPlain)[3] = htons(sizeof(key)); memcpy (asymPlain+8, key, sizeof(key)); SHA1 (pub, pubLen, asymPlain + 8 + sizeof(key)); /* Encrypt to EK */ /* Must use custom padding for TPM to decrypt it */ asymPaddedLength = asymEncLength = RSA_size (ekRsa); asymPadded = malloc (asymPaddedLength); asymEnc = malloc (asymEncLength); RSA_padding_add_PKCS1_OAEP(asymPadded, asymPaddedLength, asymPlain, sizeof(asymPlain), oaepPad, sizeof(oaepPad)); RSA_public_encrypt (asymPaddedLength, asymPadded, asymEnc, ekRsa, RSA_NO_PADDING); free (asymPadded); asymPadded = NULL; /* Encrypt challenge with key */ symEnc = malloc (chalLen + sizeof(iv)); EVP_CIPHER_CTX_init (&ctx); EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, iv); EVP_EncryptUpdate (&ctx, symEnc, &out1, chal, chalLen); EVP_EncryptFinal_ex (&ctx, symEnc+out1, &out2); EVP_CIPHER_CTX_cleanup(&ctx); symEncLength = out1 + out2; /* Create TPM_SYM_CA_ATTESTATION struct to hold encrypted cert */ symAttestLength = 28 + sizeof(iv) + symEncLength; symAttest = malloc (symAttestLength); ((UINT32 *)symAttest)[0] = htonl(symEncLength); ((UINT32 *)symAttest)[1] = htonl(TPM_ALG_AES); ((UINT16 *)symAttest)[4] = htons(TPM_ES_SYM_CBC_PKCS5PAD); ((UINT16 *)symAttest)[5] = htons(TPM_SS_NONE); ((UINT32 *)symAttest)[3] = htonl(12+sizeof(iv)); ((UINT32 *)symAttest)[4] = htonl(128); /* Key length in bits */ ((UINT32 *)symAttest)[5] = htonl(sizeof(iv)); /* Block size in bytes */ ((UINT32 *)symAttest)[6] = htonl(sizeof(iv)); /* IV size in bytes */ memcpy (symAttest+28, iv, sizeof(iv)); memcpy (symAttest+28+sizeof(iv), symEnc, symEncLength); if (trousersIVMode) { ((UINT32 *)symAttest)[0] = htonl(symEncLength + sizeof(iv)); ((UINT32 *)symAttest)[3] = htonl(12); /* Take IV to be start of symEnc */ ((UINT32 *)symAttest)[6] = htonl(0); /* IV size in bytes */ } free (symEnc); symEnc = NULL; if ((f_out = fopen (av[3], "wb")) == NULL) { fprintf (stderr, "Unable to open file %s for output\n", av[3]); exit (1); } /* Precede the two blocks with 4-byte lengths */ tt[0] = htonl (asymEncLength); fwrite (tt, 1, sizeof(UINT32), f_out); fwrite (asymEnc, 1, asymEncLength, f_out); tt[0] = htonl (symAttestLength); fwrite (tt, 1, sizeof(UINT32), f_out); if (fwrite (symAttest, 1, symAttestLength, f_out) != symAttestLength) { fprintf (stderr, "Unable to write to file %s\n", av[3]); exit (1); } fclose (f_out); /* Output RSA key representing the AIK for future use */ if ((f_out = fopen (av[4], "wb")) == NULL) { fprintf (stderr, "Unable to open file %s for output\n", av[4]); exit (1); } aikRsa = RSA_new(); aikRsa->n = BN_bin2bn (pub+pubLen-256, 256, NULL); aikRsa->e = BN_new(); BN_set_word (aikRsa->e, 0x10001); if (PEM_write_RSA_PUBKEY(f_out, aikRsa) < 0) { fprintf (stderr, "Unable to write to file %s\n", av[3]); exit (1); } fclose (f_out); printf ("Success!\n"); return 0; badproof: fprintf (stderr, "Input AIK proof file incorrect format\n"); return 1; }
static int itacns_add_cert(sc_pkcs15_card_t *p15card, int type, int authority, const sc_path_t *path, const sc_pkcs15_id_t *id, const char *label, int obj_flags, int *ext_info_ok, int *key_usage, int *x_key_usage) { int r; /* const char *label = "Certificate"; */ sc_pkcs15_cert_info_t info; sc_pkcs15_object_t obj; #ifdef ENABLE_OPENSSL X509 *x509; #endif sc_pkcs15_cert_t *cert; SC_FUNC_CALLED(p15card->card->ctx, 1); if(type != SC_PKCS15_TYPE_CERT_X509) { sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Cannot add a certificate of a type other than X.509"); return 1; } *ext_info_ok = 0; memset(&info, 0, sizeof(info)); memset(&obj, 0, sizeof(obj)); info.id = *id; info.authority = authority; if (path) info.path = *path; strlcpy(obj.label, label, sizeof(obj.label)); obj.flags = obj_flags; r = sc_pkcs15emu_add_x509_cert(p15card, &obj, &info); SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add X.509 certificate"); /* If we have OpenSSL, read keyUsage */ #ifdef ENABLE_OPENSSL r = sc_pkcs15_read_certificate(p15card, &info, &cert); SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not read X.509 certificate"); { const u8 *throwaway = cert->data; x509 = d2i_X509(NULL, &throwaway, cert->data_len); } sc_pkcs15_free_certificate(cert); if (!x509) return SC_SUCCESS; X509_check_purpose(x509, -1, 0); if(x509->ex_flags & EXFLAG_KUSAGE) { *ext_info_ok = 1; *key_usage = x509->ex_kusage; *x_key_usage = x509->ex_xkusage; } OPENSSL_free(x509); return SC_SUCCESS; #else /* ENABLE_OPENSSL */ return SC_SUCCESS; #endif /* ENABLE_OPENSSL */ }
/* loads in the certificate from the server */ int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data) { STACK_OF(X509) *sk=NULL; EVP_PKEY *pkey=NULL; SESS_CERT *sc=NULL; int i; X509 *x509=NULL; int ret=0; x509=d2i_X509(NULL,&data,(long)len); if (x509 == NULL) { SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_X509_LIB); goto err; } if ((sk=sk_X509_new_null()) == NULL || !sk_X509_push(sk,x509)) { SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_MALLOC_FAILURE); goto err; } i=ssl_verify_cert_chain(s,sk); if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)) { SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED); goto err; } ERR_clear_error(); /* but we keep s->verify_result */ s->session->verify_result = s->verify_result; /* server's cert for this session */ sc=ssl_sess_cert_new(); if (sc == NULL) { ret= -1; goto err; } if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert); s->session->sess_cert=sc; sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509; sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]); pkey=X509_get_pubkey(x509); x509=NULL; if (pkey == NULL) { SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY); goto err; } if (pkey->type != EVP_PKEY_RSA) { SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_PUBLIC_KEY_NOT_RSA); goto err; } if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE)) goto err; ret=1; err: sk_X509_free(sk); X509_free(x509); EVP_PKEY_free(pkey); return(ret); }
int LLVMFuzzerInitialize(int* argc, char*** argv) { rand_predictable = 1; SSL_library_init(); OpenSSL_add_ssl_algorithms(); ERR_load_crypto_strings(); if (RAND_reset_for_fuzzing) RAND_reset_for_fuzzing(); ctx = SSL_CTX_new(SSLv23_method()); const uint8_t* bufp = kRSAPrivateKeyDER; RSA* privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER)); assert(privkey != NULL); EVP_PKEY* pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, privkey); int ret = SSL_CTX_use_PrivateKey(ctx, pkey); assert(ret == 1); EVP_PKEY_free(pkey); bufp = kCertificateDER; X509* cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER)); assert(cert != NULL); ret = SSL_CTX_use_certificate(ctx, cert); assert(ret == 1); X509_free(cert); ret = SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:aNULL:DSS"); assert(ret == 1); X509_STORE* store = X509_STORE_new(); assert(store != NULL); bufp = kRSACACertDER; cert = d2i_X509(NULL, &bufp, sizeof(kRSACACertDER)); assert(cert != NULL); ret = SSL_CTX_add_client_CA(ctx, cert); assert(ret == 1); ret = X509_STORE_add_cert(store, cert); assert(ret == 1); X509_free(cert); bufp = kECCACertDER; cert = d2i_X509(NULL, &bufp, sizeof(kECCACertDER)); assert(cert != NULL); ret = SSL_CTX_add_client_CA(ctx, cert); assert(ret == 1); ret = X509_STORE_add_cert(store, cert); assert(ret == 1); X509_free(cert); bufp = kDSACertDER; cert = d2i_X509(NULL, &bufp, sizeof(kDSACertDER)); ret = SSL_CTX_add_client_CA(ctx, cert); assert(ret == 1); ret = X509_STORE_add_cert(store, cert); assert(ret == 1); X509_free(cert); SSL_CTX_set_cert_store(ctx, store); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); SSL_CTX_set_verify_depth(ctx, 10); #if !defined(LIBRESSL_VERSION_NUMBER) SSL_CTX_set_psk_server_callback(ctx, psk_callback); ret = SSL_CTX_use_psk_identity_hint(ctx, "ABCDEFUZZ"); assert(ret == 1); #endif /* !defined(LIBRESSL_VERSION_NUMBER) */ #if !defined(LIBRESSL_VERSION_NUMBER) && !defined(BORINGSSL_API_VERSION) ret = SSL_CTX_set_srp_username_callback(ctx, srp_callback); assert(ret == 1); ret = SSL_CTX_set_srp_cb_arg(ctx, NULL); assert(ret == 1); #endif /* !defined(LIBRESSL_VERSION_NUMBER) && !defined(BORINGSSL_API_VERSION) */ SSL_CTX_set_alpn_select_cb(ctx, alpn_callback, NULL); SSL_CTX_set_next_protos_advertised_cb(ctx, npn_callback, NULL); SSL_CTX_set_ecdh_auto(ctx, 1); return 1; }
/* * Decode a string to a key. Return 0 on success. */ int kn_decode_key(struct keynote_deckey *dc, char *key, int keytype) { void *kk = (void *) NULL; X509 *px509Cert; EVP_PKEY *pPublicKey; unsigned char *ptr = (char *) NULL, *decoded = (char *) NULL; int encoding, internalencoding, len = 0; keynote_errno = 0; if (keytype == KEYNOTE_PRIVATE_KEY) dc->dec_algorithm = keynote_get_private_key_algorithm(key, &encoding, &internalencoding); else dc->dec_algorithm = keynote_get_key_algorithm(key, &encoding, &internalencoding); if (dc->dec_algorithm == KEYNOTE_ALGORITHM_NONE) { dc->dec_key = (void *) strdup(key); if (dc->dec_key == (void *) NULL) { keynote_errno = ERROR_MEMORY; return -1; } return 0; } key = strchr(key, ':'); /* Move forward, to the Encoding. We're guaranteed * to have a ':' character, since this is a key */ key++; /* Remove ASCII encoding */ switch (encoding) { case ENCODING_NONE: break; case ENCODING_HEX: len = strlen(key) / 2; if (kn_decode_hex(key, (char **) &decoded) != 0) return -1; ptr = decoded; break; case ENCODING_BASE64: len = strlen(key); if (len % 4) /* Base64 encoding must be a multiple of 4 */ { keynote_errno = ERROR_SYNTAX; return -1; } len = 3 * (len / 4); decoded = (unsigned char *) calloc(len, sizeof(unsigned char)); ptr = decoded; if (decoded == (unsigned char *) NULL) { keynote_errno = ERROR_MEMORY; return -1; } if ((len = kn_decode_base64(key, decoded, len)) == -1) return -1; break; case ENCODING_NATIVE: decoded = strdup(key); if (decoded == (unsigned char *) NULL) { keynote_errno = ERROR_MEMORY; return -1; } len = strlen(key); ptr = decoded; break; default: keynote_errno = ERROR_SYNTAX; return -1; } /* DSA-HEX */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_DSA) && (internalencoding == INTERNAL_ENC_ASN1)) { dc->dec_key = DSA_new(); if (dc->dec_key == (DSA *) NULL) { keynote_errno = ERROR_MEMORY; return -1; } kk = dc->dec_key; if (keytype == KEYNOTE_PRIVATE_KEY) { if (d2i_DSAPrivateKey((DSA **) &kk,(const unsigned char **) &decoded, len) == (DSA *) NULL) { if (ptr != (unsigned char *) NULL) free(ptr); DSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } else { if (d2i_DSAPublicKey((DSA **) &kk, (const unsigned char **) &decoded, len) == (DSA *) NULL) { if (ptr != (unsigned char *) NULL) free(ptr); DSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } if (ptr != (unsigned char *) NULL) free(ptr); return 0; } /* RSA-PKCS1-HEX */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_RSA) && (internalencoding == INTERNAL_ENC_PKCS1)) { dc->dec_key = RSA_new(); if (dc->dec_key == (RSA *) NULL) { keynote_errno = ERROR_MEMORY; return -1; } kk = dc->dec_key; if (keytype == KEYNOTE_PRIVATE_KEY) { if (d2i_RSAPrivateKey((RSA **) &kk, (const unsigned char **) &decoded, len) == (RSA *) NULL) { if (ptr != (unsigned char *) NULL) free(ptr); RSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } if (RSA_blinding_on ((RSA *) kk, NULL) != 1) { if (ptr != (unsigned char *) NULL) free(ptr); RSA_free(kk); keynote_errno = ERROR_MEMORY; return -1; } } else { if (d2i_RSAPublicKey((RSA **) &kk, (const unsigned char **) &decoded, len) == (RSA *) NULL) { if (ptr != (unsigned char *) NULL) free(ptr); RSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } if (ptr != (unsigned char *) NULL) free(ptr); return 0; } /* X509 Cert */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_X509) && (internalencoding == INTERNAL_ENC_ASN1) && (keytype == KEYNOTE_PUBLIC_KEY)) { if ((px509Cert = X509_new()) == (X509 *) NULL) { if (ptr) free(ptr); keynote_errno = ERROR_MEMORY; return -1; } if(d2i_X509(&px509Cert, &decoded, len) == NULL) { if (ptr) free(ptr); X509_free(px509Cert); keynote_errno = ERROR_SYNTAX; return -1; } if ((pPublicKey = X509_get_pubkey(px509Cert)) == (EVP_PKEY *) NULL) { if (ptr) free(ptr); X509_free(px509Cert); keynote_errno = ERROR_SYNTAX; return -1; } /* RSA-specific */ dc->dec_key = pPublicKey->pkey.rsa; if(ptr) free(ptr); return 0; } /* BINARY keys */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_BINARY) && (internalencoding == INTERNAL_ENC_NONE)) { dc->dec_key = (void *) calloc(1, sizeof(struct keynote_binary)); if (dc->dec_key == (struct keynote_binary *) NULL) { keynote_errno = ERROR_MEMORY; return -1; } ((struct keynote_binary *) dc->dec_key)->bn_key = decoded; ((struct keynote_binary *) dc->dec_key)->bn_len = len; return RESULT_TRUE; } /* Add support for more algorithms here */ if (ptr != (unsigned char *) NULL) free(ptr); /* This shouldn't ever be reached really */ keynote_errno = ERROR_SYNTAX; return -1; }
s2n_cert_validation_code s2n_x509_validator_validate_cert_chain(struct s2n_x509_validator *validator, struct s2n_connection *conn, uint8_t *cert_chain_in, uint32_t cert_chain_len, s2n_cert_type *cert_type, struct s2n_pkey *public_key_out) { if (!validator->skip_cert_validation && !s2n_x509_trust_store_has_certs(validator->trust_store)) { return S2N_CERT_ERR_UNTRUSTED; } DEFER_CLEANUP(X509_STORE_CTX *ctx = NULL, X509_STORE_CTX_free_pointer); struct s2n_blob cert_chain_blob = {.data = cert_chain_in, .size = cert_chain_len}; DEFER_CLEANUP(struct s2n_stuffer cert_chain_in_stuffer = {{0}}, s2n_stuffer_free); if (s2n_stuffer_init(&cert_chain_in_stuffer, &cert_chain_blob) < 0) { return S2N_CERT_ERR_INVALID; } if (s2n_stuffer_write(&cert_chain_in_stuffer, &cert_chain_blob) < 0) { return S2N_CERT_ERR_INVALID; } uint32_t certificate_count = 0; X509 *server_cert = NULL; DEFER_CLEANUP(struct s2n_pkey public_key = {{{0}}}, s2n_pkey_free); s2n_pkey_zero_init(&public_key); while (s2n_stuffer_data_available(&cert_chain_in_stuffer) && certificate_count < validator->max_chain_depth) { uint32_t certificate_size = 0; if (s2n_stuffer_read_uint24(&cert_chain_in_stuffer, &certificate_size) < 0) { return S2N_CERT_ERR_INVALID; } if (certificate_size == 0 || certificate_size > s2n_stuffer_data_available(&cert_chain_in_stuffer)) { return S2N_CERT_ERR_INVALID; } struct s2n_blob asn1cert = {0}; asn1cert.data = s2n_stuffer_raw_read(&cert_chain_in_stuffer, certificate_size); asn1cert.size = certificate_size; if (asn1cert.data == NULL) { return S2N_CERT_ERR_INVALID; } const uint8_t *data = asn1cert.data; if (!validator->skip_cert_validation) { /* the cert is der encoded, just convert it. */ server_cert = d2i_X509(NULL, &data, asn1cert.size); if (!server_cert) { return S2N_CERT_ERR_INVALID; } /* add the cert to the chain. */ if (!sk_X509_push(validator->cert_chain, server_cert)) { X509_free(server_cert); return S2N_CERT_ERR_INVALID; } } /* Pull the public key from the first certificate */ if (certificate_count == 0) { if (s2n_asn1der_to_public_key_and_type(&public_key, cert_type, &asn1cert) < 0) { return S2N_CERT_ERR_INVALID; } } certificate_count++; } /* if this occurred we exceeded validator->max_chain_depth */ if (!validator->skip_cert_validation && s2n_stuffer_data_available(&cert_chain_in_stuffer)) { return S2N_CERT_ERR_MAX_CHAIN_DEPTH_EXCEEDED; } if (certificate_count < 1) { return S2N_CERT_ERR_INVALID; } if (!validator->skip_cert_validation) { X509 *leaf = sk_X509_value(validator->cert_chain, 0); if (!leaf) { return S2N_CERT_ERR_INVALID; } if (conn->verify_host_fn && !s2n_verify_host_information(validator, conn, leaf)) { return S2N_CERT_ERR_UNTRUSTED; } /* now that we have a chain, get the store and check against it. */ ctx = X509_STORE_CTX_new(); int op_code = X509_STORE_CTX_init(ctx, validator->trust_store->trust_store, leaf, validator->cert_chain); if (op_code <= 0) { return S2N_CERT_ERR_INVALID; } X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx); X509_VERIFY_PARAM_set_depth(param, validator->max_chain_depth); uint64_t current_sys_time = 0; conn->config->wall_clock(conn->config->sys_clock_ctx, ¤t_sys_time); /* this wants seconds not nanoseconds */ time_t current_time = (time_t)(current_sys_time / 1000000000); X509_STORE_CTX_set_time(ctx, 0, current_time); op_code = X509_verify_cert(ctx); if (op_code <= 0) { return S2N_CERT_ERR_UNTRUSTED; } } *public_key_out = public_key; /* Reset the old struct, so we don't clean up public_key_out */ s2n_pkey_zero_init(&public_key); return S2N_CERT_OK; }
/* Get a SERVER HELLO response from the server */ void get_server_hello(ssl_conn* ssl) { unsigned char buf[BUFSIZE]; unsigned char *p, *end; int len; int server_version, cert_length, cs_length, conn_id_length; int found; if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) { printf("Server error: %s\n", ssl_error(ntohs(*(uint16_t*)&buf[1]))); exit(1); } if (len < 11) { printf("get_server_hello: Packet too short (len = %d)\n", len); exit(1); } p = buf; if (*(p++) != SSL2_MT_SERVER_HELLO) { printf("get_server_hello: Expected SSL2 MT SERVER HELLO, got %x\n", (int)p[-1]); exit(1); } if (*(p++) != 0) { printf("get_server_hello: SESSION-ID-HIT is not 0\n"); exit(1); } if (*(p++) != 1) { printf("get_server_hello: CERTIFICATE-TYPE is not SSL CT X509 CERTIFICATE\n"); exit(1); } n2s(p, server_version); if (server_version != 2) { printf("get_server_hello: Unsupported server version %d\n", server_version); exit(1); } n2s(p, cert_length); n2s(p, cs_length); n2s(p, conn_id_length); if (len != 11 + cert_length + cs_length + conn_id_length) { printf("get_server_hello: Malformed packet size\n"); exit(1); } /* read the server certificate */ ssl->x509 = NULL; ssl->x509=d2i_X509(NULL,&p,(long)cert_length); if (ssl->x509 == NULL) { printf("get server hello: Cannot parse x509 certificate\n"); exit(1); } if (cs_length % 3 != 0) { printf("get server hello: CIPHER-SPECS-LENGTH is not a multiple of 3\n"); exit(1); } found = 0; for (end=p+cs_length; p < end; p += 3) { if ((p[0] == 0x01) && (p[1] == 0x00) && (p[2] == 0x80)) found = 1; /* SSL CK RC4 128 WITH MD5 */ } if (!found) { printf("get server hello: Remote server does not support 128 bit RC4\n"); exit(1); } if (conn_id_length > SSL2_MAX_CONNECTION_ID_LENGTH) { printf("get server hello: CONNECTION-ID-LENGTH is too long\n"); exit(1); } /* The connection id is sent back to the server in the CLIENT FINISHED packet */ ssl->conn_id_length = conn_id_length; memcpy(ssl->conn_id, p, conn_id_length); }
int main(int argc, char* argv[]) { PKCS7 *p7, *innerp7; FILE *fp = NULL; EVP_PKEY *pkey = NULL; PKCS7_SIGNER_INFO *p7i; PKCS7_RECIP_INFO *pri; BIO *mybio, *inbio; X509 *user; X509_ALGOR *md; int ret, len; unsigned char data[2048], *p, *buf; unsigned char* greet = "hello openssl"; unsigned long errorno; unsigned char* errordesc; OpenSSL_add_all_algorithms(); //必须要显式进行调用 inbio = BIO_new(BIO_s_mem()); ret = BIO_write(inbio, greet, strlen(greet)); p7 = PKCS7_new(); ret = PKCS7_set_type(p7, NID_pkcs7_signedAndEnveloped); //加载用户证书 fp = fopen("mycert4p12.cer", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 1024, fp); fclose(fp); p = data; user = d2i_X509(NULL, (const unsigned char**)&p, len); ret = PKCS7_add_certificate(p7, user); pri = PKCS7_add_recipient(p7, user); //读取私钥 fp = fopen("myprivkey.pem", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 1024, fp); fclose(fp); p = data; pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (const unsigned char**)&p, len); //第一个用户增加SignerInfo到列表中 p7i = PKCS7_add_signature(p7, user, pkey, EVP_md5()); //加载用户证书 fp = fopen("user2.cer", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 1024, fp); fclose(fp); p = data; user = d2i_X509(NULL, (const unsigned char**)&p, len); ret = PKCS7_add_certificate(p7, user); pri = PKCS7_add_recipient(p7, user); //读取私钥 fp = fopen("user2_privatekey.pem", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 1024, fp); fclose(fp); p = data; pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (const unsigned char**)&p, len); //第二个签名者增加到SignerInfo列表中 p7i = PKCS7_add_signature(p7, user, pkey, EVP_md5()); ret = PKCS7_set_cipher(p7, EVP_des_ede3_cbc()); ret = PKCS7_final(p7, inbio, 0); //制作数字信封 len = i2d_PKCS7(p7, NULL); p = buf = malloc(len); len = i2d_PKCS7(p7, &p); printf("in i2d len = %d\n", len); fp = fopen("p7signandenv.cer", "wb"); fwrite(buf, len, 1, fp); fclose(fp); PKCS7_free(p7); }
bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const { merchant.clear(); if (!IsInitialized()) return false; // One day we'll support more PKI types, but just // x509 for now: const EVP_MD* digestAlgorithm = NULL; if (paymentRequest.pki_type() == "x509+sha256") { digestAlgorithm = EVP_sha256(); } else if (paymentRequest.pki_type() == "x509+sha1") { digestAlgorithm = EVP_sha1(); } else if (paymentRequest.pki_type() == "none") { qDebug() << "PaymentRequestPlus::getMerchant : Payment request: pki_type == none"; return false; } else { qDebug() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type()); return false; } payments::X509Certificates certChain; if (!certChain.ParseFromString(paymentRequest.pki_data())) { qDebug() << "PaymentRequestPlus::getMerchant : Payment request: error parsing pki_data"; return false; } std::vector<X509*> certs; const QDateTime currentTime = QDateTime::currentDateTime(); for (int i = 0; i < certChain.certificate_size(); i++) { QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size()); QSslCertificate qCert(certData, QSsl::Der); if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) { qDebug() << "PaymentRequestPlus::getMerchant : Payment request: certificate expired or not yet active: " << qCert; return false; } #if QT_VERSION >= 0x050000 if (qCert.isBlacklisted()) { qDebug() << "PaymentRequestPlus::getMerchant : Payment request: certificate blacklisted: " << qCert; return false; } #endif const unsigned char *data = (const unsigned char *)certChain.certificate(i).data(); X509 *cert = d2i_X509(NULL, &data, certChain.certificate(i).size()); if (cert) certs.push_back(cert); } if (certs.empty()) { qDebug() << "PaymentRequestPlus::getMerchant : Payment request: empty certificate chain"; return false; } // The first cert is the signing cert, the rest are untrusted certs that chain // to a valid root authority. OpenSSL needs them separately. STACK_OF(X509) *chain = sk_X509_new_null(); for (int i = certs.size()-1; i > 0; i--) { sk_X509_push(chain, certs[i]); } X509 *signing_cert = certs[0]; // Now create a "store context", which is a single use object for checking, // load the signing cert into it and verify. X509_STORE_CTX *store_ctx = X509_STORE_CTX_new(); if (!store_ctx) { qDebug() << "PaymentRequestPlus::getMerchant : Payment request: error creating X509_STORE_CTX"; return false; } char *website = NULL; bool fResult = true; try { if (!X509_STORE_CTX_init(store_ctx, certStore, signing_cert, chain)) { int error = X509_STORE_CTX_get_error(store_ctx); throw SSLVerifyError(X509_verify_cert_error_string(error)); } // Now do the verification! int result = X509_verify_cert(store_ctx); if (result != 1) { int error = X509_STORE_CTX_get_error(store_ctx); throw SSLVerifyError(X509_verify_cert_error_string(error)); } X509_NAME *certname = X509_get_subject_name(signing_cert); // Valid cert; check signature: payments::PaymentRequest rcopy(paymentRequest); // Copy rcopy.set_signature(std::string("")); std::string data_to_verify; // Everything but the signature rcopy.SerializeToString(&data_to_verify); EVP_MD_CTX ctx; EVP_PKEY *pubkey = X509_get_pubkey(signing_cert); EVP_MD_CTX_init(&ctx); if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) || !EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) || !EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) { throw SSLVerifyError("Bad signature, invalid PaymentRequest."); } // OpenSSL API for getting human printable strings from certs is baroque. int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0); website = new char[textlen + 1]; if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) { merchant = website; } else { throw SSLVerifyError("Bad certificate, missing common name."); } // TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ? } catch (SSLVerifyError& err) { fResult = false; qDebug() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what(); } if (website) delete[] website; X509_STORE_CTX_free(store_ctx); for (unsigned int i = 0; i < certs.size(); i++) X509_free(certs[i]); return fResult; }
/* * initialize a new TLS context */ static int tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) { tlso_ctx *ctx = (tlso_ctx *)lo->ldo_tls_ctx; int i; if ( is_server ) { SSL_CTX_set_session_id_context( ctx, (const unsigned char *) "OpenLDAP", sizeof("OpenLDAP")-1 ); } #ifdef SSL_OP_NO_TLSv1 #ifdef SSL_OP_NO_TLSv1_1 #ifdef SSL_OP_NO_TLSv1_2 if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_2) SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 ); else #endif if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_1) SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 ); else #endif if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_0) SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1); else #endif if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL3 ) SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 ); else if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL2 ) SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 ); if ( lo->ldo_tls_ciphersuite && !SSL_CTX_set_cipher_list( ctx, lt->lt_ciphersuite ) ) { Debug( LDAP_DEBUG_ANY, "TLS: could not set cipher list %s.\n", lo->ldo_tls_ciphersuite, 0, 0 ); tlso_report_error(); return -1; } if ( lo->ldo_tls_cacertfile == NULL && lo->ldo_tls_cacertdir == NULL && lo->ldo_tls_cacert.bv_val == NULL ) { if ( !SSL_CTX_set_default_verify_paths( ctx ) ) { Debug( LDAP_DEBUG_ANY, "TLS: " "could not use default certificate paths", 0, 0, 0 ); tlso_report_error(); return -1; } } else { X509 *cert = NULL; if ( lo->ldo_tls_cacert.bv_val ) { const unsigned char *pp = lo->ldo_tls_cacert.bv_val; cert = d2i_X509( NULL, &pp, lo->ldo_tls_cacert.bv_len ); X509_STORE *store = SSL_CTX_get_cert_store( ctx ); if ( !X509_STORE_add_cert( store, cert )) { Debug( LDAP_DEBUG_ANY, "TLS: " "could not use CA certificate", 0, 0, 0 ); tlso_report_error(); return -1; } } if (( lt->lt_cacertfile || lt->lt_cacertdir ) && !SSL_CTX_load_verify_locations( ctx, lt->lt_cacertfile, lt->lt_cacertdir ) ) { Debug( LDAP_DEBUG_ANY, "TLS: " "could not load verify locations (file:`%s',dir:`%s').\n", lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "", lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "", 0 ); tlso_report_error(); return -1; } if ( is_server ) { STACK_OF(X509_NAME) *calist; /* List of CA names to send to a client */ calist = tlso_ca_list( lt->lt_cacertfile, lt->lt_cacertdir, cert ); if ( !calist ) { Debug( LDAP_DEBUG_ANY, "TLS: " "could not load client CA list (file:`%s',dir:`%s').\n", lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "", lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "", 0 ); tlso_report_error(); return -1; } SSL_CTX_set_client_CA_list( ctx, calist ); } if ( cert ) X509_free( cert ); } if ( lo->ldo_tls_cert.bv_val ) { const unsigned char *pp = lo->ldo_tls_cert.bv_val; X509 *cert = d2i_X509( NULL, &pp, lo->ldo_tls_cert.bv_len ); if ( !SSL_CTX_use_certificate( ctx, cert )) { Debug( LDAP_DEBUG_ANY, "TLS: could not use certificate.\n", 0,0,0); tlso_report_error(); return -1; } X509_free( cert ); } else if ( lo->ldo_tls_certfile && !SSL_CTX_use_certificate_file( ctx, lt->lt_certfile, SSL_FILETYPE_PEM ) ) { Debug( LDAP_DEBUG_ANY, "TLS: could not use certificate file `%s'.\n", lo->ldo_tls_certfile,0,0); tlso_report_error(); return -1; } /* Key validity is checked automatically if cert has already been set */ if ( lo->ldo_tls_key.bv_val ) { const unsigned char *pp = lo->ldo_tls_key.bv_val; EVP_PKEY *pkey = d2i_AutoPrivateKey( NULL, &pp, lo->ldo_tls_key.bv_len ); if ( !SSL_CTX_use_PrivateKey( ctx, pkey )) { Debug( LDAP_DEBUG_ANY, "TLS: could not use private key.\n", 0,0,0); tlso_report_error(); return -1; } EVP_PKEY_free( pkey ); } else if ( lo->ldo_tls_keyfile && !SSL_CTX_use_PrivateKey_file( ctx, lt->lt_keyfile, SSL_FILETYPE_PEM ) ) { Debug( LDAP_DEBUG_ANY, "TLS: could not use key file `%s'.\n", lo->ldo_tls_keyfile,0,0); tlso_report_error(); return -1; } if ( is_server && lo->ldo_tls_dhfile ) { DH *dh; BIO *bio; if (( bio=BIO_new_file( lt->lt_dhfile,"r" )) == NULL ) { Debug( LDAP_DEBUG_ANY, "TLS: could not use DH parameters file `%s'.\n", lo->ldo_tls_dhfile,0,0); tlso_report_error(); return -1; } if (!( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) { Debug( LDAP_DEBUG_ANY, "TLS: could not read DH parameters file `%s'.\n", lo->ldo_tls_dhfile,0,0); tlso_report_error(); BIO_free( bio ); return -1; } BIO_free( bio ); SSL_CTX_set_tmp_dh( ctx, dh ); SSL_CTX_set_options( ctx, SSL_OP_SINGLE_DH_USE ); DH_free( dh ); } if ( is_server && lo->ldo_tls_ecname ) { #ifdef OPENSSL_NO_EC Debug( LDAP_DEBUG_ANY, "TLS: Elliptic Curves not supported.\n", 0,0,0 ); return -1; #else EC_KEY *ecdh; int nid = OBJ_sn2nid( lt->lt_ecname ); if ( nid == NID_undef ) { Debug( LDAP_DEBUG_ANY, "TLS: could not use EC name `%s'.\n", lo->ldo_tls_ecname,0,0); tlso_report_error(); return -1; } ecdh = EC_KEY_new_by_curve_name( nid ); if ( ecdh == NULL ) { Debug( LDAP_DEBUG_ANY, "TLS: could not generate key for EC name `%s'.\n", lo->ldo_tls_ecname,0,0); tlso_report_error(); return -1; } SSL_CTX_set_tmp_ecdh( ctx, ecdh ); SSL_CTX_set_options( ctx, SSL_OP_SINGLE_ECDH_USE ); EC_KEY_free( ecdh ); #endif } if ( tlso_opt_trace ) { SSL_CTX_set_info_callback( ctx, tlso_info_cb ); } i = SSL_VERIFY_NONE; if ( lo->ldo_tls_require_cert ) { i = SSL_VERIFY_PEER; if ( lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND || lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD ) { i |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; } } SSL_CTX_set_verify( ctx, i, lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_ALLOW ? tlso_verify_ok : tlso_verify_cb ); #if OPENSSL_VERSION_NUMBER < 0x10100000 SSL_CTX_set_tmp_rsa_callback( ctx, tlso_tmp_rsa_cb ); #endif #ifdef HAVE_OPENSSL_CRL if ( lo->ldo_tls_crlcheck ) { X509_STORE *x509_s = SSL_CTX_get_cert_store( ctx ); if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_PEER ) { X509_STORE_set_flags( x509_s, X509_V_FLAG_CRL_CHECK ); } else if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_ALL ) { X509_STORE_set_flags( x509_s, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL ); } } #endif return 0; }
static int op_capi_get_by_subject(X509_LOOKUP *_lu,int _type,X509_NAME *_name, X509_OBJECT *_ret) { HCERTSTORE h_store; if(_name==NULL)return 0; if(_name->bytes==NULL||_name->bytes->length<=0||_name->modified) { if(i2d_X509_NAME(_name,NULL)<0)return 0; OP_ASSERT(_name->bytes->length>0); } h_store=(HCERTSTORE)_lu->method_data; switch(_type) { case X509_LU_X509: { CERT_NAME_BLOB find_para; PCCERT_CONTEXT cert; X509 *x; int ret; /*Although X509_NAME contains a canon_enc field, that "canonical" [1] encoding was just made up by OpenSSL. It doesn't correspond to any actual standard, and since it drops the initial sequence header, won't be recognized by the Crypto API. The assumption here is that CertFindCertificateInStore() will allow any appropriate variations in the encoding when it does its comparison. This is, however, emphatically not true under Wine, which just compares the encodings with memcmp(). Most of the time things work anyway, though, and there isn't really anything we can do to make the situation better. [1] A "canonical form" is defined as the one where, if you locked 10 mathematicians in a room and asked them to come up with a representation for something, it's the answer that 9 of them would give you back. I don't think OpenSSL's encoding qualifies.*/ find_para.cbData=_name->bytes->length; find_para.pbData=(unsigned char *)_name->bytes->data; cert=CertFindCertificateInStore(h_store,X509_ASN_ENCODING,0, CERT_FIND_SUBJECT_NAME,&find_para,NULL); if(cert==NULL)return 0; x=d2i_X509(NULL,(const unsigned char **)&cert->pbCertEncoded, cert->cbCertEncoded); CertFreeCertificateContext(cert); if(x==NULL)return 0; ret=X509_STORE_add_cert(_lu->store_ctx,x); X509_free(x); if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret); } break; case X509_LU_CRL: { CERT_INFO cert_info; CERT_CONTEXT find_para; PCCRL_CONTEXT crl; X509_CRL *x; int ret; ret=op_capi_retrieve_by_subject(_lu,_type,_name,_ret); if(ret>0)return ret; memset(&cert_info,0,sizeof(cert_info)); cert_info.Issuer.cbData=_name->bytes->length; cert_info.Issuer.pbData=(unsigned char *)_name->bytes->data; memset(&find_para,0,sizeof(find_para)); find_para.pCertInfo=&cert_info; crl=CertFindCRLInStore(h_store,0,0,CRL_FIND_ISSUED_BY,&find_para,NULL); if(crl==NULL)return 0; x=d2i_X509_CRL(NULL,(const unsigned char **)&crl->pbCrlEncoded, crl->cbCrlEncoded); CertFreeCRLContext(crl); if(x==NULL)return 0; ret=X509_STORE_add_crl(_lu->store_ctx,x); X509_CRL_free(x); if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret); } break; } return 0; }
static int importKeychainToX509_STORE(X509_STORE* verifyStore, char* err, size_t err_len) { int status = 1; CFArrayRef result = NULL; OSStatus osStatus; // This copies all the certificates trusted by the system (regardless of what // keychain they're // attached to) into a CFArray. if ((osStatus = SecTrustCopyAnchorCertificates(&result)) != 0) { CFStringRef statusString = SecCopyErrorMessageString(osStatus, NULL); snprintf(err, err_len, "Error enumerating certificates: %s", CFStringGetCStringPtr(statusString, kCFStringEncodingASCII)); CFRelease(statusString); status = 0; goto CLEANUP; } CFDataRef rawData = NULL; X509* x509Cert = NULL; for (CFIndex i = 0; i < CFArrayGetCount(result); i++) { SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(result, i); rawData = SecCertificateCopyData(cert); if (!rawData) { snprintf(err, err_len, "Error enumerating certificates"); status = 0; goto CLEANUP; } const uint8_t* rawDataPtr = CFDataGetBytePtr(rawData); // Parse an openssl X509 object from each returned certificate x509Cert = d2i_X509(NULL, &rawDataPtr, CFDataGetLength(rawData)); if (!x509Cert) { snprintf(err, err_len, "Error parsing X509 certificate from system keychain: %s", ERR_reason_error_string(ERR_peek_last_error())); status = 0; goto CLEANUP; } // Add the parsed X509 object to the X509_STORE verification store if (X509_STORE_add_cert(verifyStore, x509Cert) != 1) { int check_error_status = checkX509_STORE_error(err, err_len); if (!check_error_status) { status = check_error_status; goto CLEANUP; } } CFRelease(rawData); rawData = NULL; X509_free(x509Cert); x509Cert = NULL; } CLEANUP: if (result != NULL) { CFRelease(result); } if (rawData != NULL) { CFRelease(rawData); } if (x509Cert != NULL) { X509_free(x509Cert); } return status; }
static int __pkcs11h_crypto_openssl_certificate_get_expiration ( IN void * const global_data, IN const unsigned char * const blob, IN const size_t blob_size, OUT time_t * const expiration ) { X509 *x509 = NULL; __pkcs11_openssl_d2i_t d2i; ASN1_TIME *notBefore; ASN1_TIME *notAfter; (void)global_data; /*_PKCS11H_ASSERT (global_data!=NULL); NOT NEEDED*/ _PKCS11H_ASSERT (blob!=NULL); _PKCS11H_ASSERT (expiration!=NULL); *expiration = (time_t)0; if ((x509 = X509_new ()) == NULL) { goto cleanup; } d2i = (__pkcs11_openssl_d2i_t)blob; if (!d2i_X509 (&x509, &d2i, blob_size)) { goto cleanup; } notBefore = X509_get_notBefore (x509); notAfter = X509_get_notAfter (x509); if ( notBefore != NULL && notAfter != NULL && X509_cmp_current_time (notBefore) <= 0 && X509_cmp_current_time (notAfter) >= 0 && notAfter->length >= 12 ) { struct tm tm1; memset (&tm1, 0, sizeof (tm1)); tm1.tm_year = (notAfter->data[ 0] - '0') * 10 + (notAfter->data[ 1] - '0') + 100; tm1.tm_mon = (notAfter->data[ 2] - '0') * 10 + (notAfter->data[ 3] - '0') - 1; tm1.tm_mday = (notAfter->data[ 4] - '0') * 10 + (notAfter->data[ 5] - '0'); tm1.tm_hour = (notAfter->data[ 6] - '0') * 10 + (notAfter->data[ 7] - '0'); tm1.tm_min = (notAfter->data[ 8] - '0') * 10 + (notAfter->data[ 9] - '0'); tm1.tm_sec = (notAfter->data[10] - '0') * 10 + (notAfter->data[11] - '0'); *expiration = mktime (&tm1); *expiration += (int)(mktime (localtime (expiration)) - mktime (gmtime (expiration))); } cleanup: if (x509 != NULL) { X509_free (x509); x509 = NULL; } return *expiration != (time_t)0; }
int FuzzerTestOneInput(const uint8_t *buf, size_t len) { SSL *server; BIO *in; BIO *out; BIO *bio_buf; SSL_CTX *ctx; int ret; RSA *privkey; const uint8_t *bufp; EVP_PKEY *pkey; X509 *cert; #ifndef OPENSSL_NO_EC EC_KEY *ecdsakey = NULL; #endif #ifndef OPENSSL_NO_DSA DSA *dsakey = NULL; #endif uint8_t opt; if (len < 2) return 0; /* * TODO: use the ossltest engine (optionally?) to disable crypto checks. */ /* This only fuzzes the initial flow from the client so far. */ ctx = SSL_CTX_new(SSLv23_method()); /* RSA */ bufp = kRSAPrivateKeyDER; privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER)); OPENSSL_assert(privkey != NULL); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, privkey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bufp = kCertificateDER; cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER)); OPENSSL_assert(cert != NULL); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #ifndef OPENSSL_NO_EC /* ECDSA */ bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM)) == sizeof(ECDSAPrivateKeyPEM)); ecdsakey = PEM_read_bio_ECPrivateKey(bio_buf, NULL, NULL, NULL); ERR_print_errors_fp(stderr); OPENSSL_assert(ecdsakey != NULL); BIO_free(bio_buf); pkey = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(pkey, ecdsakey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSACertPEM, sizeof(ECDSACertPEM)) == sizeof(ECDSACertPEM)); cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); OPENSSL_assert(cert != NULL); BIO_free(bio_buf); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #endif #ifndef OPENSSL_NO_DSA /* DSA */ bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM)) == sizeof(DSAPrivateKeyPEM)); dsakey = PEM_read_bio_DSAPrivateKey(bio_buf, NULL, NULL, NULL); ERR_print_errors_fp(stderr); OPENSSL_assert(dsakey != NULL); BIO_free(bio_buf); pkey = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey, dsakey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, DSACertPEM, sizeof(DSACertPEM)) == sizeof(DSACertPEM)); cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); OPENSSL_assert(cert != NULL); BIO_free(bio_buf); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #endif /* TODO: Set up support for SRP and PSK */ server = SSL_new(ctx); ret = SSL_set_cipher_list(server, "ALL:eNULL:@SECLEVEL=0"); OPENSSL_assert(ret == 1); in = BIO_new(BIO_s_mem()); out = BIO_new(BIO_s_mem()); SSL_set_bio(server, in, out); SSL_set_accept_state(server); opt = (uint8_t)buf[len-1]; len--; OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); if ((opt & 0x01) != 0) { do { char early_buf[16384]; size_t early_len; ret = SSL_read_early_data(server, early_buf, sizeof(early_buf), &early_len); if (ret != SSL_READ_EARLY_DATA_SUCCESS) break; } while (1); } if (SSL_do_handshake(server) == 1) { /* Keep reading application data until error or EOF. */ uint8_t tmp[1024]; for (;;) { if (SSL_read(server, tmp, sizeof(tmp)) <= 0) { break; } } } SSL_free(server); ERR_clear_error(); SSL_CTX_free(ctx); return 0; }
int SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) { HCERTSTORE cs; X509 *cert = NULL; RSA *rsa = NULL, *pub_rsa; CAPI_DATA *cd = calloc(1, sizeof(*cd)); RSA_METHOD *my_rsa_method = calloc(1, sizeof(*my_rsa_method)); if (cd == NULL || my_rsa_method == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE); goto err; } /* search CURRENT_USER first, then LOCAL_MACHINE */ cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY"); if (cs == NULL) { CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE); goto err; } cd->cert_context = find_certificate_in_store(cert_prop, cs); CertCloseStore(cs, 0); if (!cd->cert_context) { cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY"); if (cs == NULL) { CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE); goto err; } cd->cert_context = find_certificate_in_store(cert_prop, cs); CertCloseStore(cs, 0); if (cd->cert_context == NULL) { CRYPTOAPIerr(CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE); goto err; } } /* cert_context->pbCertEncoded is the cert X509 DER encoded. */ cert = d2i_X509(NULL, (const unsigned char **) &cd->cert_context->pbCertEncoded, cd->cert_context->cbCertEncoded); if (cert == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_ASN1_LIB); goto err; } /* set up stuff to use the private key */ if (!CryptAcquireCertificatePrivateKey(cd->cert_context, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov)) { /* if we don't have a smart card reader here, and we try to access a * smart card certificate, we get: * "Error 1223: The operation was canceled by the user." */ CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY); goto err; } /* here we don't need to do CryptGetUserKey() or anything; all necessary key * info is in cd->cert_context, and then, in cd->crypt_prov. */ my_rsa_method->name = "Microsoft CryptoAPI RSA Method"; my_rsa_method->rsa_pub_enc = rsa_pub_enc; my_rsa_method->rsa_pub_dec = rsa_pub_dec; my_rsa_method->rsa_priv_enc = rsa_priv_enc; my_rsa_method->rsa_priv_dec = rsa_priv_dec; /* my_rsa_method->init = init; */ my_rsa_method->finish = finish; my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK; my_rsa_method->app_data = (char *) cd; rsa = RSA_new(); if (rsa == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE); goto err; } /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(), * so we do it here then... */ if (!SSL_CTX_use_certificate(ssl_ctx, cert)) goto err; /* the public key */ pub_rsa = cert->cert_info->key->pkey->pkey.rsa; /* SSL_CTX_use_certificate() increased the reference count in 'cert', so * we decrease it here with X509_free(), or it will never be cleaned up. */ X509_free(cert); cert = NULL; /* I'm not sure about what we have to fill in in the RSA, trying out stuff... */ /* rsa->n indicates the key size */ rsa->n = BN_dup(pub_rsa->n); rsa->flags |= RSA_FLAG_EXT_PKEY; if (!RSA_set_method(rsa, my_rsa_method)) goto err; if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa)) goto err; /* SSL_CTX_use_RSAPrivateKey() increased the reference count in 'rsa', so * we decrease it here with RSA_free(), or it will never be cleaned up. */ RSA_free(rsa); return 1; err: if (cert) X509_free(cert); if (rsa) RSA_free(rsa); else { if (my_rsa_method) free(my_rsa_method); if (cd) { if (cd->free_crypt_prov && cd->crypt_prov) CryptReleaseContext(cd->crypt_prov, 0); if (cd->cert_context) CertFreeCertificateContext(cd->cert_context); free(cd); } } return 0; }
//-------------------------------------------------------------------------------------------------- le_result_t secSocket_AddCertificate ( secSocket_Ctx_t* ctxPtr, ///< [INOUT] Secure socket context pointer const uint8_t* certificatePtr, ///< [IN] Certificate Pointer size_t certificateLen ///< [IN] Certificate Length ) { X509_STORE *store = NULL; X509 *cert = NULL; BIO *bio = NULL; le_result_t status = LE_FAULT; le_clk_Time_t currentTime; // Check input parameters if ((!ctxPtr) || (!certificatePtr) || (!certificateLen)) { return LE_BAD_PARAMETER; } OpensslCtx_t* contextPtr = GetContext(ctxPtr); if (!contextPtr) { return LE_BAD_PARAMETER; } LE_INFO("Certificate: %p Len:%zu", certificatePtr, certificateLen); // Get a BIO abstraction pointer bio = BIO_new_mem_buf((void*)certificatePtr, certificateLen); if (!bio) { LE_ERROR("Unable to allocate BIO pointer"); goto end; } // Read the DER formatted certificate from memory into an X509 structure cert = d2i_X509(NULL, &certificatePtr, certificateLen); if (!cert) { LE_ERROR("Unable to read certificate"); goto end; } // Check certificate validity currentTime = le_clk_GetAbsoluteTime(); if ((X509_cmp_time(X509_get_notBefore(cert), ¤tTime.sec) >= 0) || (X509_cmp_time(X509_get_notAfter(cert), ¤tTime.sec) <= 0)) { LE_ERROR("Current certificate expired, please add a valid certificate"); status = LE_FORMAT_ERROR; goto end; } // Get a pointer to the current certificate verification pool store = SSL_CTX_get_cert_store(contextPtr->sslCtxPtr); if (!store) { LE_ERROR("Unable to get a pointer to the X509 certificate"); goto end; } // Add certificate to the verification pool if (!X509_STORE_add_cert(store, cert)) { LE_ERROR("Unable to add certificate to pool"); goto end; } status = LE_OK; end: if (cert) { X509_free(cert); } if (bio) { BIO_free(bio); } return status; }