Beispiel #1
0
    def testParseReusableConfigInlineValues(self):
        concept_parsers.ConceptParser.ForResource(
            '--reusable-config',
            resource_args.CreateReusableConfigResourceSpec(),
            'Reusable config for this CA.',
            prefixes=True).AddToParser(self.parser)
        flags.AddInlineReusableConfigFlags(self.parser, is_ca=True)
        args = self.parser.parse_args([
            '--key-usages', 'cert_sign,crl_sign', '--extended-key-usages',
            'server_auth,client_auth', '--max-chain-length', '2'
        ])
        reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                            'us-west1',
                                                            is_ca=True)
        self.assertIsNone(reusable_config_wrapper.reusableConfig)
        values = reusable_config_wrapper.reusableConfigValues
        self.assertTrue(values.keyUsage.baseKeyUsage.certSign)
        self.assertTrue(values.keyUsage.baseKeyUsage.crlSign)
        self.assertIsNone(values.keyUsage.baseKeyUsage.digitalSignature)
        self.assertIsNone(values.keyUsage.baseKeyUsage.contentCommitment)
        self.assertIsNone(values.keyUsage.baseKeyUsage.keyEncipherment)
        self.assertIsNone(values.keyUsage.baseKeyUsage.dataEncipherment)
        self.assertIsNone(values.keyUsage.baseKeyUsage.keyAgreement)
        self.assertIsNone(values.keyUsage.baseKeyUsage.encipherOnly)
        self.assertIsNone(values.keyUsage.baseKeyUsage.decipherOnly)

        self.assertTrue(values.keyUsage.extendedKeyUsage.serverAuth)
        self.assertTrue(values.keyUsage.extendedKeyUsage.clientAuth)
        self.assertIsNone(values.keyUsage.extendedKeyUsage.codeSigning)
        self.assertIsNone(values.keyUsage.extendedKeyUsage.emailProtection)
        self.assertIsNone(values.keyUsage.extendedKeyUsage.timeStamping)
        self.assertIsNone(values.keyUsage.extendedKeyUsage.ocspSigning)

        self.assertEqual(values.caOptions.maxIssuerPathLength, 2)
        self.assertTrue(values.caOptions.isCa)
Beispiel #2
0
    def Run(self, args):
        kms_key_version_ref, ca_ref = self.ParseResourceArgs(args)
        kms_key_ref = kms_key_version_ref.Parent()
        project_ref = ca_ref.Parent().Parent()

        subject_config = flags.ParseSubjectFlags(args, is_ca=True)
        issuing_options = flags.ParseIssuingOptions(args)
        issuance_policy = flags.ParseIssuancePolicy(args)
        reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                            ca_ref.locationsId,
                                                            is_ca=True)
        lifetime = flags.ParseValidityFlag(args)
        labels = labels_util.ParseCreateArgs(
            args, self.messages.CertificateAuthority.LabelsValue)

        iam.CheckCreateCertificateAuthorityPermissions(project_ref,
                                                       kms_key_ref)

        p4sa_email = p4sa.GetOrCreate(project_ref)
        bucket_ref = storage.CreateBucketForCertificateAuthority(ca_ref)

        p4sa.AddResourceRoleBindings(p4sa_email, kms_key_ref, bucket_ref)

        new_ca = self.messages.CertificateAuthority(
            type=self.messages.CertificateAuthority.TypeValueValuesEnum.
            SELF_SIGNED,
            lifetime=lifetime,
            config=self.messages.CertificateConfig(
                reusableConfig=reusable_config_wrapper,
                subjectConfig=subject_config),
            cloudKmsKeyVersion=kms_key_version_ref.RelativeName(),
            certificatePolicy=issuance_policy,
            issuingOptions=issuing_options,
            gcsBucket=bucket_ref.bucket,
            labels=labels)

        operation = self.client.projects_locations_certificateAuthorities.Create(
            self.messages.
            PrivatecaProjectsLocationsCertificateAuthoritiesCreateRequest(
                certificateAuthority=new_ca,
                certificateAuthorityId=ca_ref.Name(),
                parent=ca_ref.Parent().RelativeName(),
                requestId=request_utils.GenerateRequestId()))

        ca_response = operations.Await(operation,
                                       'Creating Certificate Authority.')
        ca = operations.GetMessageFromResponse(
            ca_response, self.messages.CertificateAuthority)

        log.status.Print('Creating the initial Certificate Revocation List.')
        self.client.projects_locations_certificateAuthorities.PublishCrl(
            self.messages.
            PrivatecaProjectsLocationsCertificateAuthoritiesPublishCrlRequest(
                name=ca.name,
                publishCertificateRevocationListRequest=self.messages.
                PublishCertificateRevocationListRequest()))

        log.status.Print('Created Certificate Authority [{}].'.format(ca.name))
Beispiel #3
0
 def testParseReusableConfigResourceAndInlineValues(self):
     concept_parsers.ConceptParser.ForResource(
         '--reusable-config',
         resource_args.CreateReusableConfigResourceSpec('CA'),
         'Reusable config for this CA.',
         prefixes=True).AddToParser(self.parser)
     flags.AddInlineReusableConfigFlags(self.parser, is_ca=True)
     args = self.parser.parse_args([
         '--reusable-config',
         'projects/foo/locations/us/reusableConfigs/rc1', '--key-usages',
         'cert_sign,crl_sign'
     ])
     with self.AssertRaisesExceptionMatches(Exception, 'Invalid value'):
         flags.ParseReusableConfig(args, 'us-west1', is_ca=True)
Beispiel #4
0
    def _GenerateCertificateConfig(self, request, args, location):
        private_key, public_key = key_generation.RSAKeyGen(2048)
        key_generation.ExportPrivateKey(args.key_output_file, private_key)

        config = self.messages.CertificateConfig()
        config.publicKey = self.messages.PublicKey()
        config.publicKey.key = public_key
        config.publicKey.type = self.messages.PublicKey.TypeValueValuesEnum.PEM_RSA_KEY
        config.reusableConfig = flags.ParseReusableConfig(
            args, location, is_ca_command=args.is_ca_cert)
        config.subjectConfig = flags.ParseSubjectFlags(args,
                                                       is_ca=args.is_ca_cert)

        return config
Beispiel #5
0
  def _GenerateCertificateConfig(self, request, args):
    messages = privateca_base.GetMessagesModule()
    private_key, public_key = key_generation.RSAKeyGen(2048)
    key_generation.ExportPrivateKey(args.key_output_file, private_key)

    config = messages.CertificateConfig()
    config.publicKey = messages.PublicKey()
    config.publicKey.key = public_key
    config.publicKey.type = messages.PublicKey.TypeValueValuesEnum.PEM_RSA_KEY
    config.reusableConfig = flags.ParseReusableConfig(args)

    config.subjectConfig = flags.ParseSubjectFlags(args, is_ca=False)

    return config
Beispiel #6
0
    def testParseReusableConfigNoResourceAndNoInlineCertificateValues(self):
        concept_parsers.ConceptParser.ForResource(
            '--reusable-config',
            resource_args.CreateReusableConfigResourceSpec(),
            'Reusable config for this CA.',
            prefixes=True).AddToParser(self.parser)
        flags.AddInlineReusableConfigFlags(self.parser, is_ca=False)
        args = self.parser.parse_args([])
        reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                            'us-west',
                                                            is_ca=False)

        self.assertIsNone(reusable_config_wrapper.reusableConfig)
        self.assertEqual(
            reusable_config_wrapper.reusableConfigValues.caOptions.isCa, False)
Beispiel #7
0
 def testParseReusableConfigInlineCertificateValues(self):
     concept_parsers.ConceptParser.ForResource(
         '--reusable-config',
         resource_args.CreateReusableConfigResourceSpec('certificate'),
         'Reusable config for this certificate.',
         prefixes=True).AddToParser(self.parser)
     flags.AddInlineReusableConfigFlags(self.parser, is_ca=False)
     args = self.parser.parse_args([
         '--key-usages', 'cert_sign,crl_sign', '--extended-key-usages',
         'server_auth,client_auth', '--no-is-ca-cert'
     ])
     reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                         'us-west1',
                                                         is_ca=False)
     self.assertEqual(
         reusable_config_wrapper.reusableConfigValues.caOptions.isCa, False)
Beispiel #8
0
 def testParseReusableConfigShortResourceArg(self):
     concept_parsers.ConceptParser.ForResource(
         '--reusable-config',
         resource_args.CreateReusableConfigResourceSpec('CA'),
         'Reusable config for this CA.',
         prefixes=True).AddToParser(self.parser)
     flags.AddInlineReusableConfigFlags(self.parser, is_ca=True)
     args = self.parser.parse_args(['--reusable-config', 'rc1'])
     reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                         'us-central1',
                                                         is_ca=True)
     self.assertEqual(
         reusable_config_wrapper.reusableConfig,
         'projects/privateca-data/locations/us-central1/reusableConfigs/rc1'
     )
     self.assertEqual(reusable_config_wrapper.reusableConfigValues, None)
Beispiel #9
0
 def testParseReusableConfigMaxChainLengthIgnored(self):
     concept_parsers.ConceptParser.ForResource(
         '--reusable-config',
         resource_args.CreateReusableConfigResourceSpec(),
         'Reusable config for this CA.',
         prefixes=True).AddToParser(self.parser)
     flags.AddInlineReusableConfigFlags(self.parser, is_ca=False)
     args = self.parser.parse_args(
         ['--no-is-ca-cert', '--max-chain-length', '1'])
     reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                         'us-west1',
                                                         is_ca=False)
     self.assertEqual(
         reusable_config_wrapper.reusableConfigValues.caOptions.isCa, False)
     self.assertIsNone(reusable_config_wrapper.reusableConfigValues.
                       caOptions.maxIssuerPathLength)
Beispiel #10
0
 def testParseReusableConfigIsCa(self):
     concept_parsers.ConceptParser.ForResource(
         '--reusable-config',
         resource_args.CreateReusableConfigResourceSpec(),
         'Reusable config for this CA.',
         prefixes=True).AddToParser(self.parser)
     flags.AddInlineReusableConfigFlags(self.parser, is_ca=True)
     args = self.parser.parse_args([])
     reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                         'us-west1',
                                                         is_ca=True)
     self.assertTrue(
         reusable_config_wrapper.reusableConfigValues.caOptions.isCa)
     self.assertTrue(reusable_config_wrapper.reusableConfigValues.keyUsage.
                     baseKeyUsage.certSign)
     self.assertTrue(reusable_config_wrapper.reusableConfigValues.keyUsage.
                     baseKeyUsage.crlSign)
Beispiel #11
0
  def Run(self, args):
    kms_key_version_ref, ca_ref = self.ParseResourceArgs(args)
    kms_key_ref = kms_key_version_ref.Parent()
    project_ref = ca_ref.Parent().Parent()

    common_name, subject = flags.ParseSubject(args.subject)
    subject_alt_names = flags.ParseSanFlags(args)
    issuing_options = flags.ParseIssuingOptions(args)
    issuance_policy = flags.ParseIssuancePolicy(args)
    reusable_config_wrapper = flags.ParseReusableConfig(args)
    lifetime = flags.ParseValidityFlag(args)
    labels = labels_util.ParseCreateArgs(
        args, self.messages.CertificateAuthority.LabelsValue)

    iam.CheckCreateCertificateAuthorityPermissions(project_ref, kms_key_ref)

    p4sa_email = p4sa.GetOrCreate(project_ref)
    bucket_ref = storage.CreateBucketForCertificateAuthority(ca_ref)

    p4sa.AddResourceRoleBindings(p4sa_email, kms_key_ref, bucket_ref)

    new_ca = self.messages.CertificateAuthority(
        type=self.messages.CertificateAuthority.TypeValueValuesEnum.SELF_SIGNED,
        lifetime=lifetime,
        config=self.messages.CertificateConfig(
            reusableConfig=reusable_config_wrapper,
            subjectConfig=self.messages.SubjectConfig(
                commonName=common_name,
                subject=subject,
                subjectAltName=subject_alt_names)),
        cloudKmsKeyVersion=kms_key_version_ref.RelativeName(),
        certificatePolicy=issuance_policy,
        issuingOptions=issuing_options,
        gcsBucket=bucket_ref.bucket,
        labels=labels)

    operation = self.client.projects_locations_certificateAuthorities.Create(
        self.messages
        .PrivatecaProjectsLocationsCertificateAuthoritiesCreateRequest(
            certificateAuthority=new_ca,
            certificateAuthorityId=ca_ref.Name(),
            parent=ca_ref.Parent().RelativeName(),
            requestId=request_utils.GenerateRequestId()))

    return operations.Await(operation, 'Creating Certificate Authority.')
Beispiel #12
0
    def testParseReusableConfigFullyQualifiedResourceArg(self):
        reusable_config_id = 'projects/foo/locations/us-west1/reusableConfigs/rc1'
        concept_parsers.ConceptParser.ForResource(
            '--reusable-config',
            resource_args.CreateReusableConfigResourceSpec('CA'),
            'Reusable config for this CA.',
            prefixes=True).AddToParser(self.parser)
        flags.AddInlineReusableConfigFlags(self.parser, is_ca=True)
        args = self.parser.parse_args(
            ['--reusable-config', reusable_config_id])

        # We expect the parser to ignore the 'us-central1' hint here since the
        # resource name explicitly specifies 'us-west1'.
        reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                            'us-central1',
                                                            is_ca=True)
        self.assertEqual(reusable_config_wrapper.reusableConfig,
                         reusable_config_id)
        self.assertEqual(reusable_config_wrapper.reusableConfigValues, None)
Beispiel #13
0
 def testParseReusableConfigMaxChainLength(self):
     concept_parsers.ConceptParser.ForResource(
         '--reusable-config',
         resource_args.CreateReusableConfigResourceSpec(),
         'Reusable config for this CA.',
         prefixes=True).AddToParser(self.parser)
     flags.AddInlineReusableConfigFlags(self.parser, is_ca=True)
     args = self.parser.parse_args(['--max-chain-length', '1'])
     reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                         'us-west1',
                                                         is_ca=True)
     self.assertTrue(
         reusable_config_wrapper.reusableConfigValues.caOptions.isCa)
     self.assertEqual(
         reusable_config_wrapper.reusableConfigValues.caOptions.
         maxIssuerPathLength, 1)
     self.assertTrue(reusable_config_wrapper.reusableConfigValues.keyUsage.
                     baseKeyUsage.certSign)
     self.assertTrue(reusable_config_wrapper.reusableConfigValues.keyUsage.
                     baseKeyUsage.crlSign)
Beispiel #14
0
    def Run(self, args):
        kms_key_version_ref, ca_ref, issuer_ref = _ParseResourceArgs(args)
        kms_key_ref = kms_key_version_ref.Parent()
        project_ref = ca_ref.Parent().Parent()

        subject_config = flags.ParseSubjectFlags(args, is_ca=True)
        issuing_options = flags.ParseIssuingOptions(args)
        issuance_policy = flags.ParseIssuancePolicy(args)
        reusable_config_wrapper = flags.ParseReusableConfig(args,
                                                            ca_ref.locationsId,
                                                            is_ca=True)
        lifetime = flags.ParseValidityFlag(args)
        labels = labels_util.ParseCreateArgs(
            args, self.messages.CertificateAuthority.LabelsValue)

        iam.CheckCreateCertificateAuthorityPermissions(project_ref,
                                                       kms_key_ref)
        if issuer_ref:
            iam.CheckCreateCertificatePermissions(issuer_ref)

        p4sa_email = p4sa.GetOrCreate(project_ref)
        bucket_ref = storage.CreateBucketForCertificateAuthority(ca_ref)

        p4sa.AddResourceRoleBindings(p4sa_email, kms_key_ref, bucket_ref)

        new_ca = self.messages.CertificateAuthority(
            type=self.messages.CertificateAuthority.TypeValueValuesEnum.
            SUBORDINATE,
            lifetime=lifetime,
            config=self.messages.CertificateConfig(
                reusableConfig=reusable_config_wrapper,
                subjectConfig=subject_config),
            cloudKmsKeyVersion=kms_key_version_ref.RelativeName(),
            certificatePolicy=issuance_policy,
            issuingOptions=issuing_options,
            gcsBucket=bucket_ref.bucket,
            labels=labels)

        operations.Await(
            self.client.projects_locations_certificateAuthorities.Create(
                self.messages.
                PrivatecaProjectsLocationsCertificateAuthoritiesCreateRequest(
                    certificateAuthority=new_ca,
                    certificateAuthorityId=ca_ref.Name(),
                    parent=ca_ref.Parent().RelativeName(),
                    requestId=request_utils.GenerateRequestId())),
            'Creating Certificate Authority.')

        csr_response = self.client.projects_locations_certificateAuthorities.GetCsr(
            self.messages.
            PrivatecaProjectsLocationsCertificateAuthoritiesGetCsrRequest(
                name=ca_ref.RelativeName()))
        csr = csr_response.pemCsr

        if args.create_csr:
            files.WriteFileContents(args.csr_output_file, csr)
            log.status.Print(
                "Created Certificate Authority [{}] and saved CSR to '{}'.".
                format(ca_ref.RelativeName(), args.csr_output_file))
            return

        if issuer_ref:
            ca_certificate = self._SignCsr(issuer_ref, csr, lifetime)
            self._ActivateCertificateAuthority(ca_ref, ca_certificate)
            log.status.Print('Created Certificate Authority [{}].'.format(
                ca_ref.RelativeName()))
            return

        # This should not happen because of the required arg group, but it protects
        # us in case of future additions.
        raise exceptions.OneOfArgumentsRequiredException([
            '--issuer', '--create-csr'
        ], ('To create a subordinate CA, please provide either an issuer or the '
            '--create-csr flag to output a CSR to be signed by another issuer.'
            ))
Beispiel #15
0
def CreateCAFromArgs(args, is_subordinate):
  """Creates a CA object from CA create flags.

  Args:
    args: The parser that contains the flag values.
    is_subordinate: If True, a subordinate CA is returned, otherwise a root CA.

  Returns:
    A tuple for the CA to create with (CA object, CA ref, issuer).
  """

  client = privateca_base.GetClientInstance()
  messages = privateca_base.GetMessagesModule()

  ca_ref, source_ca_ref, issuer_ref = _ParseCAResourceArgs(
      args)
  source_ca = None

  if source_ca_ref:
    source_ca = client.projects_locations_certificateAuthorities.Get(
        messages.PrivatecaProjectsLocationsCertificateAuthoritiesGetRequest(
            name=source_ca_ref.RelativeName()))
    if not source_ca:
      raise exceptions.InvalidArgumentException(
          '--from-ca', 'The provided source CA could not be retrieved.')

  tier = flags.ParseTierFlag(args)
  keyspec = flags.ParseKeySpec(args)
  if tier == messages.CertificateAuthority.TierValueValuesEnum.DEVOPS and keyspec.cloudKmsKeyVersion:
    raise exceptions.InvalidArgumentException(
        '--kms-key-version',
        'The DevOps tier does not support user-specified KMS keys.')

  subject_config = messages.SubjectConfig(
      subject=messages.Subject(), subjectAltName=messages.SubjectAltNames())
  if args.IsSpecified('subject'):
    subject_config.commonName, subject_config.subject = flags.ParseSubject(args)
  elif source_ca:
    subject_config.commonName = source_ca.config.subjectConfig.commonName
    subject_config.subject = source_ca.config.subjectConfig.subject

  if flags.SanFlagsAreSpecified(args):
    subject_config.subjectAltName = flags.ParseSanFlags(args)
  elif source_ca:
    subject_config.subjectAltName = source_ca.config.subjectConfig.subjectAltName
  flags.ValidateSubjectConfig(subject_config, is_ca=True)

  issuing_options = flags.ParseIssuingOptions(args)
  if source_ca and not args.IsSpecified('publish_ca_cert'):
    issuing_options.includeCaCertUrl = source_ca.issuingOptions.includeCaCertUrl
  if source_ca and not args.IsSpecified('publish_crl'):
    issuing_options.includeCrlAccessUrl = source_ca.issuingOptions.includeCrlAccessUrl

  issuance_policy = flags.ParseIssuancePolicy(args)
  if source_ca and not issuance_policy:
    issuance_policy = source_ca.certificatePolicy

  reusable_config_wrapper = flags.ParseReusableConfig(
      args, ca_ref.locationsId, is_ca=True)
  if source_ca and not flags.ReusableConfigFlagsAreSpecified(args):
    reusable_config_wrapper = source_ca.config.reusableConfig

  lifetime = flags.ParseValidityFlag(args)
  if source_ca and not args.IsSpecified('validity'):
    lifetime = source_ca.lifetime

  labels = labels_util.ParseCreateArgs(
      args, messages.CertificateAuthority.LabelsValue)

  new_ca = messages.CertificateAuthority(
      tier=tier,
      type=messages.CertificateAuthority.TypeValueValuesEnum.SUBORDINATE
      if is_subordinate else
      messages.CertificateAuthority.TypeValueValuesEnum.SELF_SIGNED,
      lifetime=lifetime,
      config=messages.CertificateConfig(
          reusableConfig=reusable_config_wrapper, subjectConfig=subject_config),
      keySpec=keyspec,
      certificatePolicy=issuance_policy,
      issuingOptions=issuing_options,
      gcsBucket=None,
      labels=labels)

  return (new_ca, ca_ref, issuer_ref)