~ubuntu-branches/ubuntu/precise/puppet/precise-security

« back to all changes in this revision

Viewing changes to spec/unit/ssl/certificate_authority_spec.rb

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-07-10 07:58:03 UTC
  • Revision ID: package-import@ubuntu.com-20120710075803-og8iubg2a90dtk7f
Tags: 2.7.11-1ubuntu2.1
* SECURITY UPDATE: Multiple July 2012 security issues
  - debian/patches/2.7.17-Puppet-July-2012-CVE-fixes.patch: upstream
    patch to fix multiple security issues.
  - CVE-2012-3864: arbitrary file read on master from authenticated
    clients
  - CVE-2012-3865: arbitrary file delete or denial of service on master
    from authenticated clients
  - CVE-2012-3866: last_run_report.yaml report file is world readable and
    leads to arbitrary file read on master by an agent
  - CVE-2012-3867: insufficient input validation for agent cert hostnames

Show diffs side-by-side

added added

removed removed

Lines of Context:
246
246
      # Stub out the factory
247
247
      Puppet::SSL::CertificateFactory.stubs(:build).returns "my real cert"
248
248
 
249
 
      @request_content = stub "request content stub", :subject => @name
 
249
      @request_content = stub "request content stub", :subject => OpenSSL::X509::Name.new([['CN', @name]])
250
250
      @request = stub 'request', :name => @name, :request_extensions => [], :subject_alt_names => [], :content => @request_content
251
251
 
252
252
      # And the inventory
303
303
 
304
304
      it "should use a certificate type of :ca" do
305
305
        Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
306
 
          args[0] == :ca
 
306
          args[0].should == :ca
307
307
        end.returns "my real cert"
308
308
        @ca.sign(@name, :ca, @request)
309
309
      end
310
310
 
311
311
      it "should pass the provided CSR as the CSR" do
312
312
        Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
313
 
          args[1] == @request
 
313
          args[1].should == @request
314
314
        end.returns "my real cert"
315
315
        @ca.sign(@name, :ca, @request)
316
316
      end
317
317
 
318
318
      it "should use the provided CSR's content as the issuer" do
319
319
        Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
320
 
          args[2].subject == "myhost"
 
320
          args[2].subject.to_s.should == "/CN=myhost"
321
321
        end.returns "my real cert"
322
322
        @ca.sign(@name, :ca, @request)
323
323
      end
324
324
 
325
325
      it "should pass the next serial as the serial number" do
326
326
        Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
327
 
          args[3] == @serial
 
327
          args[3].should == @serial
328
328
        end.returns "my real cert"
329
329
        @ca.sign(@name, :ca, @request)
330
330
      end
452
452
        @cert.stubs :save
453
453
      end
454
454
 
 
455
      it "should reject CSRs whose CN doesn't match the name for which we're signing them" do
 
456
        # Shorten this so the test doesn't take too long
 
457
        Puppet[:keylength] = 1024
 
458
        key = Puppet::SSL::Key.new('the_certname')
 
459
        key.generate
 
460
 
 
461
        csr = Puppet::SSL::CertificateRequest.new('the_certname')
 
462
        csr.generate(key)
 
463
 
 
464
        expect do
 
465
          @ca.check_internal_signing_policies('not_the_certname', csr, false)
 
466
        end.to raise_error(
 
467
          Puppet::SSL::CertificateAuthority::CertificateSigningError,
 
468
          /common name "the_certname" does not match expected certname "not_the_certname"/
 
469
        )
 
470
      end
 
471
 
 
472
      describe "when validating the CN" do
 
473
        before :all do
 
474
          Puppet[:keylength] = 1024
 
475
          @signing_key = Puppet::SSL::Key.new('my_signing_key')
 
476
          @signing_key.generate
 
477
        end
 
478
 
 
479
        [
 
480
         'completely_okay',
 
481
         'sure, why not? :)',
 
482
         'so+many(things)-are=allowed.',
 
483
         'this"is#just&madness%you[see]',
 
484
         'and even a (an?) \\!',
 
485
         'waltz, nymph, for quick jigs vex bud.',
 
486
         '{552c04ca-bb1b-11e1-874b-60334b04494e}'
 
487
        ].each do |name|
 
488
          it "should accept #{name.inspect}" do
 
489
            csr = Puppet::SSL::CertificateRequest.new(name)
 
490
            csr.generate(@signing_key)
 
491
 
 
492
            @ca.check_internal_signing_policies(name, csr, false)
 
493
          end
 
494
        end
 
495
 
 
496
        [
 
497
         'super/bad',
 
498
         "not\neven\tkind\rof",
 
499
         "ding\adong\a",
 
500
         "hidden\b\b\b\b\b\bmessage",
 
501
         "☃ :("
 
502
        ].each do |name|
 
503
          it "should reject #{name.inspect}" do
 
504
            # We aren't even allowed to make objects with these names, so let's
 
505
            # stub that to simulate an invalid one coming from outside Puppet
 
506
            Puppet::SSL::CertificateRequest.stubs(:validate_certname)
 
507
            csr = Puppet::SSL::CertificateRequest.new(name)
 
508
            csr.generate(@signing_key)
 
509
 
 
510
            expect do
 
511
              @ca.check_internal_signing_policies(name, csr, false)
 
512
            end.to raise_error(
 
513
              Puppet::SSL::CertificateAuthority::CertificateSigningError,
 
514
              /subject contains unprintable or non-ASCII characters/
 
515
            )
 
516
          end
 
517
        end
 
518
      end
 
519
 
455
520
      it "should reject a critical extension that isn't on the whitelist" do
456
521
        @request.stubs(:request_extensions).returns [{ "oid" => "banana",
457
522
                                                       "value" => "yumm",
458
523
                                                       "critical" => true }]
459
 
        expect { @ca.sign(@name) }.to raise_error(
 
524
        expect { @ca.check_internal_signing_policies(@name, @request, false) }.to raise_error(
460
525
          Puppet::SSL::CertificateAuthority::CertificateSigningError,
461
526
          /request extensions that are not permitted/
462
527
        )
466
531
        @request.stubs(:request_extensions).returns [{ "oid" => "peach",
467
532
                                                       "value" => "meh",
468
533
                                                       "critical" => false }]
469
 
        expect { @ca.sign(@name) }.to raise_error(
 
534
        expect { @ca.check_internal_signing_policies(@name, @request, false) }.to raise_error(
470
535
          Puppet::SSL::CertificateAuthority::CertificateSigningError,
471
536
          /request extensions that are not permitted/
472
537
        )
479
544
                                                     { "oid" => "subjectAltName",
480
545
                                                       "value" => "DNS:foo",
481
546
                                                       "critical" => true }]
482
 
        expect { @ca.sign(@name) }.to raise_error(
 
547
        expect { @ca.check_internal_signing_policies(@name, @request, false) }.to raise_error(
483
548
          Puppet::SSL::CertificateAuthority::CertificateSigningError,
484
549
          /request extensions that are not permitted/
485
550
        )
487
552
 
488
553
      it "should reject a subjectAltName for a non-DNS value" do
489
554
        @request.stubs(:subject_alt_names).returns ['DNS:foo', 'email:bar@example.com']
490
 
        expect { @ca.sign(@name, true) }.to raise_error(
 
555
        expect { @ca.check_internal_signing_policies(@name, @request, true) }.to raise_error(
491
556
          Puppet::SSL::CertificateAuthority::CertificateSigningError,
492
557
          /subjectAltName outside the DNS label space/
493
558
        )
497
562
        @request.content.stubs(:subject).
498
563
          returns(OpenSSL::X509::Name.new([["CN", "*.local"]]))
499
564
 
500
 
        expect { @ca.sign(@name) }.to raise_error(
 
565
        expect { @ca.check_internal_signing_policies('*.local', @request, false) }.to raise_error(
501
566
          Puppet::SSL::CertificateAuthority::CertificateSigningError,
502
567
          /subject contains a wildcard/
503
568
        )
505
570
 
506
571
      it "should reject a wildcard subjectAltName" do
507
572
        @request.stubs(:subject_alt_names).returns ['DNS:foo', 'DNS:*.bar']
508
 
        expect { @ca.sign(@name, true) }.to raise_error(
 
573
        expect { @ca.check_internal_signing_policies(@name, @request, true) }.to raise_error(
509
574
          Puppet::SSL::CertificateAuthority::CertificateSigningError,
510
575
          /subjectAltName contains a wildcard/
511
576
        )