1// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import "ios/web/public/session/crw_session_certificate_policy_cache_storage.h"
6
7#include "net/cert/x509_certificate.h"
8#include "net/cert/x509_util.h"
9#include "net/test/cert_test_util.h"
10#include "net/test/test_data_directory.h"
11#include "testing/gtest/include/gtest/gtest.h"
12#import "testing/gtest_mac.h"
13#include "testing/platform_test.h"
14
15#if !defined(__has_feature) || !__has_feature(objc_arc)
16#error "This file requires ARC support."
17#endif
18
19namespace {
20// Checks for equality between |cert_storage1| and |cert_storage2|.
21bool CertStoragesAreEqual(CRWSessionCertificateStorage* cert_storage1,
22                          CRWSessionCertificateStorage* cert_storage2) {
23  return net::x509_util::CryptoBufferEqual(
24             cert_storage1.certificate->cert_buffer(),
25             cert_storage2.certificate->cert_buffer()) &&
26         cert_storage1.host == cert_storage2.host &&
27         cert_storage1.status == cert_storage2.status;
28}
29// Checks for equality between |cache_storage1| and |cache_storage2|.
30bool CacheStoragesAreEqual(
31    CRWSessionCertificatePolicyCacheStorage* cache_storage1,
32    CRWSessionCertificatePolicyCacheStorage* cache_storage2) {
33  NSArray* certs1 = [cache_storage1.certificateStorages allObjects];
34  NSArray* certs2 = [cache_storage2.certificateStorages allObjects];
35  if (certs1.count != certs2.count)
36    return false;
37  for (NSUInteger i = 0; i < certs1.count; ++i) {
38    if (!CertStoragesAreEqual(certs1[i], certs2[i]))
39      return false;
40  }
41  return true;
42}
43}  // namespace
44
45class CRWSessionCertificatePolicyCacheStorageTest : public PlatformTest {
46 protected:
47  CRWSessionCertificatePolicyCacheStorageTest()
48      : cache_storage_([[CRWSessionCertificatePolicyCacheStorage alloc] init]) {
49    // Set up |cache_storage_|.
50    scoped_refptr<net::X509Certificate> cert =
51        net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
52    NSMutableSet* certs = [[NSMutableSet alloc] init];
53    [certs addObject:[[CRWSessionCertificateStorage alloc]
54                         initWithCertificate:cert
55                                        host:"test1.com"
56                                      status:net::CERT_STATUS_REVOKED]];
57    [cache_storage_ setCertificateStorages:certs];
58  }
59
60 protected:
61  CRWSessionCertificatePolicyCacheStorage* cache_storage_;
62};
63
64// Tests that unarchiving CRWSessionCertificatePolicyCacheStorage data results
65// in an equivalent storage.
66TEST_F(CRWSessionCertificatePolicyCacheStorageTest, EncodeDecode) {
67  NSData* data = [NSKeyedArchiver archivedDataWithRootObject:cache_storage_
68                                       requiringSecureCoding:NO
69                                                       error:nil];
70  NSKeyedUnarchiver* unarchiver =
71      [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil];
72  unarchiver.requiresSecureCoding = NO;
73  id decoded = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey];
74  EXPECT_TRUE(CacheStoragesAreEqual(cache_storage_, decoded));
75}
76
77using CRWSessionCertificateStorageTest = PlatformTest;
78
79// Tests that unarchiving a CRWSessionCertificateStorage returns nil if the
80// certificate data does not correctly decode to a certificate.
81TEST_F(CRWSessionCertificateStorageTest, InvalidCertData) {
82  NSKeyedArchiver* archiver =
83      [[NSKeyedArchiver alloc] initRequiringSecureCoding:NO];
84  [archiver encodeObject:[@"not a  cert" dataUsingEncoding:NSUTF8StringEncoding]
85                  forKey:web::kCertificateSerializationKey];
86  [archiver encodeObject:@"host" forKey:web::kHostSerializationKey];
87  [archiver encodeObject:@(net::CERT_STATUS_INVALID)
88                  forKey:web::kStatusSerializationKey];
89  [archiver finishEncoding];
90  NSData* data = [archiver encodedData];
91
92  NSKeyedUnarchiver* unarchiver =
93      [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil];
94  unarchiver.requiresSecureCoding = NO;
95  id decoded = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey];
96  EXPECT_FALSE(decoded);
97}
98