- s3e = sqlite3_bind_blob_wrapper(this->insertResponse, 1,
- CFDataGetBytePtr(responseData),
- CFDataGetLength(responseData), SQLITE_TRANSIENT);
-
- /* responses.responderURI */
- if (!s3e) {
- CFDataRef uriData = NULL;
- if (localResponderURI) {
- uriData = CFURLCreateData(kCFAllocatorDefault, localResponderURI,
- kCFStringEncodingUTF8, false);
- }
- if (uriData) {
- s3e = sqlite3_bind_blob_wrapper(this->insertResponse, 2,
- CFDataGetBytePtr(uriData),
- CFDataGetLength(uriData), SQLITE_TRANSIENT);
- CFRelease(uriData);
- } else {
- s3e = sqlite3_bind_null(this->insertResponse, 2);
- }
- }
- /* responses.expires */
- if (!s3e) s3e = sqlite3_bind_double(this->insertResponse, 3,
- SecOCSPResponseGetExpirationTime(ocspResponse));
- /* responses.lastUsed */
- if (!s3e) s3e = sqlite3_bind_double(this->insertResponse, 4,
- SecOCSPResponseVerifyTime(ocspResponse));
-
- /* Execute the insert statement. */
- if (!s3e) s3e = sqlite3_step(this->insertResponse);
- require_noerr(s3e = sec_sqlite3_reset(this->insertResponse, s3e), errOut);
-
- sqlite3_int64 responseId = sqlite3_last_insert_rowid(this->s3h);
-
- /* Now add a link record for every singleResponse in the ocspResponse. */
- SecAsn1OCSPSingleResponse **responses;
- for (responses = ocspResponse->responseData.responses;
- *responses; ++responses) {
- SecAsn1OCSPSingleResponse *resp = *responses;
- SecAsn1OCSPCertID *certId = &resp->certID;
-
- s3e = sqlite3_bind_blob_wrapper(this->insertLink, 1,
- certId->algId.algorithm.Data, certId->algId.algorithm.Length,
- SQLITE_TRANSIENT);
- if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->insertLink, 2,
- certId->issuerNameHash.Data, certId->issuerNameHash.Length,
- SQLITE_TRANSIENT);
- if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->insertLink, 3,
- certId->issuerPubKeyHash.Data, certId->issuerPubKeyHash.Length,
- SQLITE_TRANSIENT);
- if (!s3e) s3e = sqlite3_bind_blob_wrapper(this->insertLink, 4,
- certId->serialNumber.Data, certId->serialNumber.Length,
- SQLITE_TRANSIENT);
- if (!s3e) s3e = sqlite3_bind_int64(this->insertLink, 5,
- responseId);
-
- /* Execute the insert statement. */
- if (!s3e) s3e = sqlite3_step(this->insertLink);
- require_noerr(s3e = sec_sqlite3_reset(this->insertLink, s3e), errOut);
- }
-
-errOut:
- if (s3e) {
- ocspErrorLog("ocsp cache add failed: %s", sqlite3_errmsg(this->s3h));
- /* @@@ Blow away the cache and create a new db. */
+ __block CFErrorRef localError = NULL;
+ __block bool ok = true;
+ ok &= SecDbPerformWrite(this->db, &localError, ^(SecDbConnectionRef dbconn) {
+ ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) {
+ __block sqlite3_int64 responseId;
+ ok = SecDbWithSQL(dbconn, insertResponseSQL, &localError, ^bool(sqlite3_stmt *insertResponse) {
+ if (ok)
+ ok = SecDbBindBlob(insertResponse, 1,
+ CFDataGetBytePtr(responseData),
+ CFDataGetLength(responseData),
+ SQLITE_TRANSIENT, &localError);
+
+ /* responses.responderURI */
+ if (ok) {
+ CFDataRef uriData = NULL;
+ if (localResponderURI) {
+ uriData = CFURLCreateData(kCFAllocatorDefault, localResponderURI,
+ kCFStringEncodingUTF8, false);
+ }
+ if (uriData) {
+ ok = SecDbBindBlob(insertResponse, 2,
+ CFDataGetBytePtr(uriData),
+ CFDataGetLength(uriData),
+ SQLITE_TRANSIENT, &localError);
+ CFRelease(uriData);
+ } else {
+ // Since we use SecDbClearBindings this shouldn't be needed.
+ //ok = SecDbBindNull(insertResponse, 2, &localError);
+ }
+ }
+ /* responses.expires */
+ if (ok)
+ ok = SecDbBindDouble(insertResponse, 3,
+ SecOCSPResponseGetExpirationTime(ocspResponse),
+ &localError);
+ /* responses.lastUsed */
+ if (ok)
+ ok = SecDbBindDouble(insertResponse, 4,
+ SecOCSPResponseVerifyTime(ocspResponse),
+ &localError);
+
+ /* Execute the insert statement. */
+ if (ok)
+ ok = SecDbStep(dbconn, insertResponse, &localError, NULL);
+
+ responseId = sqlite3_last_insert_rowid(SecDbHandle(dbconn));
+ return ok;
+ });
+
+ /* Now add a link record for every singleResponse in the ocspResponse. */
+ if (ok) ok = SecDbWithSQL(dbconn, insertLinkSQL, &localError, ^bool(sqlite3_stmt *insertLink) {
+ SecAsn1OCSPSingleResponse **responses;
+ for (responses = ocspResponse->responseData.responses;
+ *responses; ++responses) {
+ SecAsn1OCSPSingleResponse *resp = *responses;
+ SecAsn1OCSPCertID *certId = &resp->certID;
+ if (ok) ok = SecDbBindBlob(insertLink, 1,
+ certId->algId.algorithm.Data,
+ certId->algId.algorithm.Length,
+ SQLITE_TRANSIENT, &localError);
+ if (ok) ok = SecDbBindBlob(insertLink, 2,
+ certId->issuerNameHash.Data,
+ certId->issuerNameHash.Length,
+ SQLITE_TRANSIENT, &localError);
+ if (ok) ok = SecDbBindBlob(insertLink, 3,
+ certId->issuerPubKeyHash.Data,
+ certId->issuerPubKeyHash.Length,
+ SQLITE_TRANSIENT, &localError);
+ if (ok) ok = SecDbBindBlob(insertLink, 4,
+ certId->serialNumber.Data,
+ certId->serialNumber.Length,
+ SQLITE_TRANSIENT, &localError);
+ if (ok) ok = SecDbBindInt64(insertLink, 5, responseId, &localError);
+
+ /* Execute the insert statement. */
+ if (ok) ok = SecDbStep(dbconn, insertLink, &localError, NULL);
+ if (ok) ok = SecDbReset(insertLink, &localError);
+ }
+ return ok;
+ });
+ if (!ok)
+ *commit = false;
+ });
+ });
+ if (!ok) {
+ secerror("_SecOCSPCacheAddResponse failed: %@", localError);