سؤال

لدي تطبيق عمل يحدد اتصال SSL بخادم. يستخدم الخادم شهادة موقعة ذاتيا ويقوم العميل بتحميل سلسلة سلطة الشهادة لإخبارها أن الخادم على ما يرام للثقة. لقد فعلت ذلك برمز مثل هذا على العميل:

SSL_METHOD* method = TLSv1_client_method();
_ctx = SSL_CTX_new(method);
if ( SSL_CTX_load_verify_locations(_ctx, "ca-all.crt", NULL) != 1 )
{
    return false;
}
_ssl = SSL_new(_ctx);
int val = SSL_set_fd(_ssl, _socket->GetFD());
if ( val != SSL_SUCCESS )
{
    int err = SSL_get_error(_ssl, val);
    return false;
}
val = SSL_connect(_ssl);

وعلى الخادم:

  if ( SSL_CTX_use_certificate_chain_file( g_ctx, "ca-chain1.crt" ) <= 0 ) {
    return 1;
  }
  ppem_file = getenv( "PEM_FILE" );
  if ( ppem_file == NULL ) {
    ppem_file = pem_file;
  }
  if ( SSL_CTX_use_certificate_file( g_ctx, ppem_file,
                                     SSL_FILETYPE_PEM ) <= 0 ) {
    return 1;
  }
  if ( SSL_CTX_use_PrivateKey_file( g_ctx, ppem_file,
                                    SSL_FILETYPE_PEM ) <= 0 ) {
    return 2;
  }

أحاول تعديل هذا الرمز بحيث يتحقق الخادم أيضًا من شهادة نظير العميل (موقعة ذاتيًا ، باستخدام نفس المصدر مثل الخادم) وتواجه القليل من المتاعب. لم أجد وثائق "نظرة عامة مفاهيمية" جيدة في أي مكان ، ويبدو أن هذا بمثابة عقبة نموذجية مع مكتبات OpenSSL.

على العميل ، أضفت هذا بعد استدعاء SSL_CTX_LOAD_VERIFY_LOCATIONS ():

if ( SSL_CTX_use_certificate_file(_ctx, "generic_client.pem", SSL_FILETYPE_PEM ) != 1 )
{
    return false;
}

على الخادم ، أضفت هذا بعد استدعاء SSL_CTX_USE_PRIVANEKEY_FILE ():

  STACK_OF(X509_NAME) *list;
  list = SSL_load_client_CA_file( "ca_chain2.crt" );
  if( list == NULL ) {
    return 4;
  }
  SSL_CTX_set_client_CA_list( g_ctx, list );
  SSL_CTX_set_verify( g_ctx, SSL_VERIFY_PEER, NULL );

فشل الاتصال لأن الشهادة لا تتحقق من صحة. يبدو أن العميل يقوم بتحميل الشهادة بشكل جيد ، وإذا قمت بتعليق خط SSL_CTX_SET_VERIFY ، يتصل العميل دون أي مشكلة (لأنه لم يتم التحقق من شهادته أبدًا).

يبدو أن الخادم لا يعتقد أن سلسلة سلطة شهادة العميل جيدة. ماذا أفتقد هنا؟

من سطر الأوامر الذي يمكنني تشغيله: OpenSSL تحقق من -لسلان ca -chain2.crt generic_client.pem ويمر ، لذلك لدي بيانات الشهادة الصحيحة المتاحة ، يجب أن أستخدمها بشكل خاطئ بطريقة ما.

هل كانت مفيدة؟

المحلول

على الخادم ، يجب عليك أيضًا الاتصال SSL_CTX_load_verify_locations(). تخبر هذه الوظيفة الخادم عن الشهادات التي يجب استخدامها للتحقق من الشهادة ؛ ال SSL_CTX_set_client_CA_list() تعمل الدالة على تعيين قائمة CAS المسموح بها التي يتم إرسالها إلى العميل في المصافحة. كلاهما مطلوب.

(تحتاج أيضًا SSL_CTX_use_PrivateKey_file() استدعاء العميل ، بعد use_certificate_file اتصل ، لكنني أعتقد أنك تفعل ذلك وتركت للتو).

نصائح أخرى

SSL_CTX_SET_CLIENT_CA_LIST يعين كاليفورنيا قائمة. تتميز شهادة CA ، بحكم التعريف ، عن شهادة المستخدم (على سبيل المثال لديها مجموعة بت CA). لذلك أوصيك بإنشاء CA مناسب (شهادة CA التي تم توقيعها ذاتيًا) ، واستخدم ذلك للتوقيع على كل من العميل وشهادة الخادم. أفترض أن OpenSSL لا يتوقع أن يستخدم العميل بالفعل شهادة CA للتواصل أيضًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top