Provided by: erlang-manpages_16.b.3-dfsg-1ubuntu2_all bug


       public_key -  API module for public key infrastructure.


       This  module  provides functions to handle public key infrastructure. It can encode/decode
       different file formats (PEM, openssh), sign and verify  digital  signatures  and  validate
       certificate paths and certificate revocation lists.


         * public_key  requires the crypto and asn1 applications, the latter since R16 (hopefully
           the runtime dependency on asn1 will be removed again in the future).

         * Supports RFC  5280   -  Internet  X.509  Public  Key  Infrastructure  Certificate  and
           Certificate Revocation List (CRL) Profile

         * Supports  PKCS-1  - RSA Cryptography Standard

         * Supports  DSS- Digital Signature Standard (DSA - Digital Signature Algorithm)

         * Supports  PKCS-3  - Diffie-Hellman Key Agreement Standard

         * Supports  PKCS-5 - Password-Based Cryptography Standard

         * Supports  PKCS-8 - Private-Key Information Syntax Standard

         * Supports  PKCS-10 - Certification Request Syntax Standard


       All records used in this manual are generated from ASN.1 specifications and are documented
       in the User's Guide. See Public key records and X.509 Certificate records.

       Use the following include directive to get access  to  the  records  and  constant  macros
       described here and in the User's Guide.


       Data Types

       oid() - a tuple of integers as generated by the ASN1 compiler.

       boolean() = true | false

       string() = [bytes()]

       der_encoded() = binary()

       pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey' |
           'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo' |
           'PrivateKeyInfo' | 'CertificationRequest' | 'ECPrivateKey'|

       pem_entry () = {pki_asn1_type(), binary(), %% DER or encrypted DER
                 not_encrypted | cipher_info()}

       cipher_info()  =  {"RC2-CBC | "DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)} |

       rsa_public_key()  = #'RSAPublicKey'{}

       rsa_private_key() = #'RSAPrivateKey'{}

       dsa_public_key() = {integer(),  #'Dss-Parms'{}}

       dsa_private_key() = #'DSAPrivateKey'{}

       ec_public_key()  = {#'ECPoint'{}, #'EcpkParameters'{} | {namedCurve, oid()}}

       ec_private_key()  = #'ECPrivateKey'{}

        public_crypt_options() = [{rsa_pad, rsa_padding()}].

        rsa_padding() =  'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding'
           | 'rsa_no_padding'

        rsa_digest_type()  = 'md5' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'

        dss_digest_type()  = 'sha'

        ecdsa_digest_type()  = 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'

        crl_reason()  = unspecified | keyCompromise | cACompromise | affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn |  aACompromise

        ssh_file()  = openssh_public_key | rfc4716_public_key |
           known_hosts | auth_keys


       compute_key(OthersKey, MyKey)->
       compute_key(OthersKey, MyKey, Params)->


                 OthersKey = #'ECPoint'{} | binary(), MyKey = #'ECPrivateKey'{} | binary()
                 Params = #'DHParameter'{}

              Compute shared secret

       decrypt_private(CipherText, Key) -> binary()
       decrypt_private(CipherText, Key, Options) -> binary()


                 CipherText = binary()
                 Key = rsa_private_key()
                 Options = public_crypt_options()

              Public key decryption using the private key. See also crypto:private_decrypt/4

       decrypt_public(CipherText, Key) - > binary()
       decrypt_public(CipherText, Key, Options) - > binary()


                 CipherText = binary()
                 Key = rsa_public_key()
                 Options = public_crypt_options()

              Public key decryption using the public key. See also crypto:public_decrypt/4

       der_decode(Asn1type, Der) -> term()


                 Asn1Type = atom()
                    ASN.1 type present in the public_key applications asn1 specifications.
                 Der = der_encoded()

              Decodes a public key ASN.1 DER encoded entity.

       der_encode(Asn1Type, Entity) -> der_encoded()


                 Asn1Type = atom()
                    Asn1 type present in the public_key applications ASN.1 specifications.
                 Entity = term()
                   The erlang representation of Asn1Type

              Encodes a public key entity with ASN.1 DER encoding.

       generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{}


                  Params = #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{}

              Generates a new keypair

       pem_decode(PemBin) -> [pem_entry()]


                 PemBin = binary()
                   Example {ok, PemBin} = file:read_file("cert.pem").

              Decode PEM binary data and return entries as ASN.1 DER encoded entities.

       pem_encode(PemEntries) -> binary()


                  PemEntries = [pem_entry()]

              Creates a PEM binary

       pem_entry_decode(PemEntry) -> term()
       pem_entry_decode(PemEntry, Password) -> term()


                  PemEntry = pem_entry()
                  Password = string()

              Decodes  a  PEM entry. pem_decode/1 returns a list of PEM entries. Note that if the
              PEM entry is of type 'SubjectPublickeyInfo'  it  will  be  further  decoded  to  an
              rsa_public_key() or dsa_public_key().

       pem_entry_encode(Asn1Type, Entity) -> pem_entry()
       pem_entry_encode(Asn1Type, Entity, {CipherInfo, Password}) -> pem_entry()


                 Asn1Type = pki_asn1_type()
                 Entity = term()
                   The  Erlang  representation of Asn1Type. If Asn1Type is 'SubjectPublicKeyInfo'
                   then Entity must be either an rsa_public_key() or a dsa_public_key() and  this
                   function will create the appropriate 'SubjectPublicKeyInfo' entry.
                 CipherInfo = cipher_info()
                 Password = string()

              Creates a PEM entry that can be feed to pem_encode/1.

       encrypt_private(PlainText, Key) -> binary()


                 PlainText = binary()
                 Key = rsa_private_key()

              Public key encryption using the private key. See also crypto:private_encrypt/4

       encrypt_public(PlainText, Key) -> binary()


                 PlainText = binary()
                 Key = rsa_public_key()

              Public key encryption using the public key. See also crypto:public_encrypt/4

       pkix_decode_cert(Cert, otp|plain) -> #'Certificate'{} | #'OTPCertificate'{}


                 Cert = der_encoded()

              Decodes  an  ASN.1  DER  encoded  PKIX  certificate.  The  otp  option will use the
              customized ASN.1 specification OTP-PKIX.asn1  for  decoding  and  also  recursively
              decode most of the standard parts.

       pkix_encode(Asn1Type, Entity, otp | plain) -> der_encoded()


                 Asn1Type = atom()
                   The ASN.1 type can be 'Certificate', 'OTPCertificate' or a subtype of either .
                 Entity = #'Certificate'{} | #'OTPCertificate'{} | a valid subtype

              DER  encodes  a  PKIX x509 certificate or part of such a certificate. This function
              must  be  used  for  encoding  certificates  or  parts  of  certificates  that  are
              decoded/created  in the otp format, whereas for the plain format this function will
              directly call der_encode/2.

       pkix_is_issuer(Cert, IssuerCert) -> boolean()


                 Cert = der_encode() | #'OTPCertificate'{}
                 IssuerCert = der_encode() | #'OTPCertificate'{}

              Checks if IssuerCert issued Cert

       pkix_is_fixed_dh_cert(Cert) -> boolean()


                 Cert = der_encode() | #'OTPCertificate'{}

              Checks if a Certificate is a fixed Diffie-Hellman Cert.

       pkix_is_self_signed(Cert) -> boolean()


                 Cert = der_encode() | #'OTPCertificate'{}

              Checks if a Certificate is self signed.

       pkix_issuer_id(Cert, IssuedBy) -> {ok, IssuerID} | {error, Reason}


                 Cert = der_encode() | #'OTPCertificate'{}
                 IssuedBy = self | other
                 IssuerID = {integer(), {rdnSequence, [#'AttributeTypeAndValue'{}]}}
                   The issuer id consists of the serial number and the issuers name.
                 Reason = term()

              Returns the issuer id.

       pkix_normalize_name(Issuer) -> Normalized


                 Issuer = {rdnSequence,[#'AttributeTypeAndValue'{}]}
                 Normalized = {rdnSequence, [#'AttributeTypeAndValue'{}]}

              Normalizes a issuer name so that it can be easily compared to another issuer name.

       pkix_path_validation(TrustedCert, CertChain, Options) -> {ok, {PublicKeyInfo, PolicyTree}}
       | {error, {bad_cert, Reason}}


                  TrustedCert = #'OTPCertificate'{} | der_encode() | unknown_ca | selfsigned_peer
                   Normally  a  trusted certificate but it can also be one of the path validation
                   errors  unknown_ca    or  selfsigned_peer    that  can  be  discovered   while
                   constructing  the  input  to  this function and that should be run through the
                  CertChain = [der_encode()]
                   A list of DER encoded  certificates  in  trust  order  ending  with  the  peer
                  Options = proplists:proplists()
                 PublicKeyInfo  =  {?'rsaEncryption'  |  ?'id-dsa', rsa_public_key() | integer(),
                 'NULL' | 'Dss-Parms'{}}
                  PolicyTree = term()
                   At the moment this will always be an empty list as Policies are not  currently
                  Reason  =  cert_expired  |  invalid_issuer  |  invalid_signature | unknown_ca |
                 selfsigned_peer    |    name_not_permitted    |    missing_basic_constraint    |
                 invalid_key_usage | crl_reason()

              Performs  a  basic path validation according to RFC 5280. However CRL validation is
              done separately by pkix_crls_validate/3  and should be  called  from  the  supplied

                {verify_fun, fun()}:
                  The fun should be defined as:

                fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
                                                          {extension, #'Extension'{}},
                    InitialUserState :: term()) ->
                     {valid, UserState :: term()} | {valid_peer, UserState :: term()} |
                     {fail, Reason :: term()} | {unknown, UserState :: term()}.

                  If  the verify callback fun returns {fail, Reason}, the verification process is
                  immediately stopped. If the verify callback fun returns {valid, UserState}, the
                  verification  process  is  continued,  this can be used to accept specific path
                  validation errors such as selfsigned_peer  as  well  as  verifying  application
                  specific   extensions.  If  called  with  an  extension  unknown  to  the  user
                  application the return value {unknown, UserState} should be used.

                {max_path_length, integer()}:
                   The max_path_length is the  maximum  number  of  non-self-issued  intermediate
                  certificates  that  may  follow  the  peer certificate in a valid certification
                  path. So if max_path_length is 0 the PEER must be signed by the trusted ROOT-CA
                  directly,  if  1  the  path  can be PEER, CA, ROOT-CA, if it is 2 PEER, CA, CA,
                  ROOT-CA and so on.

       pkix_crls_validate(OTPCertificate, DPAndCRLs, Options) -> CRLStatus()


                  OTPCertificate = #'OTPCertificate'{}
                  DPAndCRLs = [{DP::#'DistributionPoint'{} ,CRL::#'CertificateList'{}}]
                  Options = proplists:proplists()
                  CRLStatus() = valid | {bad_cert, revocation_status_undetermined}  |  {bad_cert,
                 {revoked, crl_reason()}}

              Performs  CRL  validation.  It  is  intended  to  be  called from the verify fun of

                {update_crl, fun()}:
                  The fun has the following type spec:

                 fun(#'DistributionPoint'{}, #'CertificateList'{}) -> #'CertificateList'{}

                  The fun should use the information in the distribution  point  to  acesses  the
                  lates possible version of the CRL. If this fun is not specified public_key will
                  use the default implementation:

                 fun(_DP, CRL) -> CRL end

       pkix_sign(#'OTPTBSCertificate'{}, Key) -> der_encode()


                 Key = rsa_public_key() | dsa_public_key()

              Signs a 'OTPTBSCertificate'. Returns the corresponding der encoded certificate.

       pkix_sign_types(AlgorithmId) -> {DigestType, SignatureType}


                 AlgorithmId = oid()
                   Signature oid from a certificate or a certificate revocation list
                 DigestType = rsa_digest_type() | dss_digest_type()
                 SignatureType = rsa | dsa

              Translates signature algorithm oid to erlang digest and signature types.

       pkix_verify(Cert, Key) -> boolean()


                 Cert = der_encode()
                 Key = rsa_public_key() | dsa_public_key()

              Verify PKIX x.509 certificate signature.

       sign(Msg, DigestType, Key) -> binary()


                 Msg = binary() | {digest,binary()}
                   The msg is either the binary "plain text" data to  be  signed  or  it  is  the
                   hashed value of "plain text" i.e. the digest.
                 DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()
                 Key = rsa_private_key() | dsa_private_key() | ec_private_key()

              Creates a digital signature.

       ssh_decode(SshBin, Type) -> [{public_key(), Attributes::list()}]


                 SshBin = binary()
                   Example {ok, SshBin} = file:read_file("known_hosts").
                  Type = public_key | ssh_file()
                   If  Type  is  public_key  the  binary  may be either a rfc4716 public key or a
                   openssh public key.

              Decodes a ssh file-binary. In the case of know_hosts or auth_keys  the  binary  may
              include  one  or  more  lines  of the file. Returns a list of public keys and their
              attributes, possible attribute values depends on the file type represented  by  the

                rfc4716 attributes - see RFC 4716:
                  {headers, [{string(), utf8_string()}]}

                auth_key attributes - see man sshd :
                  {comment,  string()}{options,  [string()]}{bits,  integer()} - In ssh version 1

                known_host attributes - see man sshd:
                  {hostnames, [string()]}{comment, string()}{bits, integer()} - In ssh version  1

       ssh_encode([{Key, Attributes}], Type) -> binary()


                 Key = public_key()
                 Attributes = list()
                 Type = ssh_file()

              Encodes  a  list  of  ssh  file  entries  (public keys and attributes) to a binary.
              Possible attributes depends on the file type, see  ssh_decode/2

       verify(Msg, DigestType, Signature, Key) -> boolean()


                 Msg = binary() | {digest,binary()}
                   The msg is either the binary "plain text" data or it is the  hashed  value  of
                   "plain text" i.e. the digest.
                 DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type()
                 Signature = binary()
                 Key = rsa_public_key() | dsa_public_key() | ec_public_key()

              Verifies a digital signature