openssl - Pourquoi le rappel d'agrafage OCSP est-il appelé APRES le rappel de vérification?



openssl ocsp server (1)

Je ne suis pas un expert OpenSSL, mais j'ai essayé d'écrire du code pour gérer l'agrafage OCSP pour un client se connectant à un serveur sécurisé SSL. Ma compréhension de OCSP est qu'il est utilisé pour prouver que le certificat présenté n'a pas été révoqué, ce qui signifie que je n'ai pas besoin de gérer la gestion des LCR publiées par l'émetteur.

J'utilise SSL_CTX_set_verify pour définir un callback pour gérer la vérification des certificats (bien, gérer les exceptions au processus de vérification interne d'OpenSSL Je suppose, mais je ne trouve pas de preuve que ce processus interne ne vérifie pas l'état de révocation du certificat) mon code utilise cette opportunité pour vérifier que l'émetteur est fiable (ou sinon, l'émetteur de l'émetteur est approuvé, et ainsi de suite jusqu'à ce que la chaîne soit approuvée ou rejetée), ainsi que d'autres choses telles que le certificat n'est pas expiré . (Cela aussi peut être déjà vérifié, mais ce n'est pas vraiment important pour ma question).

J'ai modifié mon code en ajoutant

SSL_set_tlsext_status_type(<the ssl object>, TLSEXT_STATUSTYPE_ocsp); 
SSL_CTX_set_tlsext_status_cb(<the context>, ssl_cb_ocsp_verify);

et puis je peux obtenir la réponse et la vérifier dans le gestionnaire. Jusqu'ici tout va bien!

Mais la chose la plus étrange est que je reçois le rappel OCSP après avoir reçu le gestionnaire SSL_CTX_set_verify. Pour ma pensée (certes naïve), cela signifie que j'ai deux options:

1) Vérifiez l'état de révocation dans le rappel de vérification, soit en utilisant la liste de révocation de certificats, soit en effectuant ma propre requête OCSP. Si je fais cela, il n'y a aucun intérêt à faire quoi que ce soit dans le rappel OCSP, puisque j'ai déjà déterminé l'état de révocation du certificat. 2) Ne pas vérifier l'état de révocation dans le rappel de vérification, et espérer que le gestionnaire OCSP est appelé.

J'ai remarqué que le gestionnaire OCSP est appelé avant le gestionnaire de vérification si la réponse du serveur n'inclut pas un message OCSP agrafé. Donc une possibilité est que je place un drapeau quelque part 'no_ocsp' à 0 ​​initialement, et puis si j'obtiens le callback OCSP sans message attaché, le mettre à 1. Puis dans le gestionnaire de vérification je peux vérifier ceci pour essayer de déterminer si le Le gestionnaire OCSP sera appelé plus tard. Cela ressemble un peu à une voiture qui se déverrouille à mesure que quelqu'un s'approche, et si la personne qui s'approche met la mauvaise touche, elle se verrouille elle-même - en d'autres termes, elle ne peut sûrement pas être la «bonne» sécurité!

Donc, je dois avoir un malentendu fondamental sur la façon d'utiliser OCSP, OpenSSL, ou les deux! Qu'est-ce que je fais mal?

(J'ai vu des questions similaires qui expliquent comment obtenir le message agrafé OCSP, mais ma question porte sur la façon dont vous l'utilisez de manière sensée, compte tenu de l'ordre des rappels.) Pour être clair: je peux obtenir l'OCSP_RESPONSE sans des problèmes)


La troisième option consisterait à demander des points CRL et une réponse OCSP, puis à vous valider dans le bon ordre.

Vous validez la réponse agrafée OCSP dans le rappel, en utilisant OCSP_basic_verify. Ensuite, une fois la connexion établie, vous vérifiez la CRL en

X509_STORE_CTX* ctx = ...

// fill up ctx, if not yet initialized
ctx->chain = chain;
ctx->get_crl = []( X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x ) -> int
{ .. your method to download CRL .. }
// disable additional CRL lookup by the library
ctx->lookup_crls = [] (X509_STORE_CTX *ctx, X509_NAME *nm) ->STACK_OF( X509_CRL ) * { return nullptr; };
// other possible options are: X509_V_FLAG_EXTENDED_CRL_SUPPORT, X509_V_FLAG_CRL_CHECK_ALL, X509_V_FLAG_USE_DELTAS
ctx->param->flags = X509_V_FLAG_CRL_CHECK;

// this will evaluate how well the CRL fits the leaf certificate you want to validate
ctx->check_revocation(ctx);

// this validates the CRL itself, if it is signed and stuff
// 0 - bad
// 1 - okay
int ok = ctx->check_crl(ctx, m_crl);

//  This gives actual revocation result
// 0 - bad (ctx->error = X509_V_ERR_CERT_REVOKED or something else)
// 1 - okay
// 2 - CRL_REASON_REMOVE_FROM_CRL
int result = ctx->cert_crl(ctx, m_crl, leafCertificate);