5G-MAG / rt-5gms-application-function

5G Media Streaming - Application Function
https://www.5g-mag.com/streaming
Other
11 stars 6 forks source link

Implement M1 Server Certificates Provisioning API #17

Closed rjb1000 closed 1 year ago

rjb1000 commented 1 year ago

Specification

In this reference implementation, each Server Certificate resource shall be uniquely identified by a UUID that is assigned by the 5GMS AF at the point of creation.

Design

The API for server certificates provisioning at M1 requires the use of SSL functions for creating private keys, certificate signing requests and public certificates.

We have two choices:

  1. Handle the certificate management inside the application function using an external library.
    • Open5GS includes both the GnuTLS and OpenSSL libraries. Either of these can be used to provide the functionality required. OpenSSL is feature rich and under active development, so is a good choice.
    • Ties the implementation into one way to do the certificate management, the implemented method.
  2. Use a program which is external to the application function to perform the certificate and key management for us.
    • We can produce a simple version of this external process which generates self signed certificates, private keys and CSRs.
    • Would allow others to implement more exotic certificate management program (e.g. using Let's Encrypt or a corporate certificate generation API)

The second option gives us more choice when it comes to installation and configuration and would allow us to create more complex demonstrations or have an AF instance running in a 5G-MAG administered cloud instance that would be able to configure AS instances with certificates able to be authenticated by any browser. Therefore the rest of this design will focus on the design of the external certificate manage process and use when dealing with M1 server certificate requests.

External Certificate Management

This should be able to manage a local or remote repository of certificates and keys depending upon the implementation.

Syntax:

CertMgmt -hPrint command line help and exit.
CertMgmt -c newcsr <id> <commonName> [<altName>...]Create a new private key and output CSR in PEM format.
CertMgmt -c newcert <id> <commonName> [<altName>...]Create a new private key and self signed public certificate.
CertMgmt -c publiccert <id>Output the public certificate for the certificate with id in PEM format.
CertMgmt -c servercert <id>Output the private key and public certificate for the certificate with id in PEM format.
CertMgmt -c setcert <id>Set the public certificate using the PEM data provided on stdin.
CertMgmt -c revoke <id>Revoke the certificate with id.
CertMgmt -c delete <id>Revoke and delete the certificate with id.
CertMgmt -c list [<id>...]

Common return codes: 0 = Success 1 = Problem with command line parameters 2 = Problem with certificate/key management

Other return codes may be used by specific commands to signal other issues, please see the individual commands for supplementary meanings for return codes.

ETags for locally stored CSR and public PEM certificates shall be the SHA256 hash of the CSR or public PEM certificate as a hexadecimal string. For externally managed certificates the provided ETag may be passed through, if no ETag is provided then the SHA256 of the public PEM certificate will be used.

newcsr

This operation will generate a private key in the store and use it to create a CSR. An ETag, Last-Modified and Cache-Control header will be output to stdout followed by the CSR in PEM format.

The CSR will include the commonName as the CN field in the subject and the commonName and altName​s will be included as DNS: entries in the subject alternative names extension.

Extra return codes: 3 - Already a certificate or CSR using that id.

newcert

This operation will generate a private key and public certificate in the store.

The public certificate will include the commonName as the CN field in the subject and the commonName and altName​s will be included as DNS: entries in the subject alternative names extension.

Use the publiccert or servercert commands to retrieve the public certificate (and private key).

Extra return codes: 3 - Already a certificate or CSR using that id.

publiccert

Output the public certificate for the given id. This will output an ETag, Last-Modified (with the modification timestamp of the certificate in IMF date-time format as defined in RFC 7231) and a Cache-Control header, followed by the public certificate which then may be followed by zero or more intermediate CA certificates in PEM format to stdout. If the id refers to a newcsr certificate that has not been uploaded using setcert, then return with exit code 8. If the id is not found then return with exit code 4.

Extra return codes: 4 - Certificate not found 8 - Public Certificate not yet available.

servercert

Output the private key and public certificate for the given id. This will output the public certificate and private key first which then may be followed by zero or more intermediate CA certificates in PEM format to stdout.

Extra return codes: 4 - Certificate not found

setcert

This command accepts a signed pubic certificate in PEM format on stdin which will be checked and stored with the private key for the same id. The incoming certificate will be checked to see that the key matches the private key registered against this id. It is also an error to use this command to set a certificate for an id that did not use newcsr to generate a CSR, or one where a public certificate has already been registered.

Extra return codes: 3 - Already a certificate or CSR using that id. 4 - Id not found 5 - No CSR issued 6 - Key does not match the private key

revoke

Revoke a public certificate and private key pair. This will mark the public certificate and private key, identified by id, as revoked and cause an update to any CRL associated.

Extra return codes: 4 - Certificate not found 7 - Certificate already revoked

delete

This will revoke and delete a public certificate and private key pair from the store. If the certificate has not previously been revoked, then it is revoked and will cause a CRL update. The public certificate and private key are then removed from the key store.

list

This lists the id and subject of private keys and certificates in the store. If any id​s are given then the list is limited to those id​s, if one or more of those id​s cannot be found then the command will use return code 4.

The output list will be a tab separated list of certificate id, certificate subject (if available) and comma separated flags ("revoked", "expired", "awaiting"), e.g.:

b9e980db-aea3-48e8-995b-17a2fef4cf1c<tab><tab>awaiting
5e7998dd-ef29-4d44-b59a-8da6d45ac7ae<tab>C=GB, L=London, O=5G-MAG, CN=msas-test.example.com<tab>revoked
843d7557-b452-4f1d-acb6-bc3a0c3006bc<tab>C=GB, L=London, O=5G-MAG, CN=msas01.example.com<tab>revoked, expired
0dfce645-d66c-49b2-9dab-2973908ea4f0<tab>C=GB, L=London, O=5G-MAG, CN=msas01.example.com<tab>expired
577b1dd4-6c44-44a3-807d-170bf5c833b6<tab>C=GB, L=London, O=5G-MAG, CN=msas01.example.com<tab>

The example shows:

Extra return codes: 4 - Certificate not found

M1 ServerCertificatesProvisioning API

In all these ${CertMgmt} represents the configured external certificate management command.

createOrReserveServerCertificate

If the request query parameter csr is truepresent then this is a reservation operation; otherwise it a creation operation.

reservation

  1. Generate a UUID to use as a certificate id.
  2. Execute ${CertMgmt} -c newcsr ${uuid} ${canonicalDomainName} (if canonicalDomainName is not known at this point use "localhost") and capture the stdout.
    1. If the command return code was 0 then copy the Etag, Last-Modified and Cache-Control headers from the captured stdout to the M1 client response and return the rest of the captured stdout as the body of the response with mime-type "application/x-pem-file" and status code 200. The Location header shall be used to return the resource path with the chosen UUID.
    2. If the command return code was not 0 then return a 500 status code with mime-type "application/problem+json" and a ProblemDetails indicating that the certificate reservation was unsuccessful.

creation

  1. If not done so already, allocate the provisioning session to an application server and remember the canonicalDomainName.
  2. Check to see if a certificate and key have already been generated for this application server.
    • Use ${CertMgmt} -c list and look for a subject with a CN field of ${canonicalDomainName} in the stdout.
    • If the certificate already exists then return the found certificate id in the Location header and respond with a 200 status code. No further processing is required for this request.
  3. Generate a UUID to use as a certificate id.
  4. Execute ${CertMgmt} -c newcert ${uuid} ${canonicalDomainName}.
  5. Return a 200 status code with the Location header set to the resource path including the generated UUID, there is no body data with this response.

uploadServerCertificate

  1. Use ${CertMgmt} -c setcert ${certificateId} and push the request body to stdin.
    1. If the return code is 0 send a 204 status code with no body as a response to the M1 client.
    2. If the return code is 3 then send a 403 status code with a ProblemDetail indicating that a certificate already exists.
    3. If the return code is 4 then send a 404 status code with a ProblemDetail indicating that no such certificateId exists.
    4. If the return code is 5 then send a 400 status code with a ProblemDetail indicating that a CSR was never generated for this certificate Id.
    5. If the return code is 6 then send a 400 status code with a ProblemDetail indicating that the public certificate provided does not match the key.
    6. For all other non-zero return codes send a 500 status code with a ProblemDetail indicating there was a certificate management problem.

retrieveServerCertificate

  1. Use ${CertMgmt} -c publiccert ${certificateId} and capture the stdout.
    1. If the return code is 0 send a response to the M1 client with status code 200, mime-type "application/x-pem-file", a copy of the ETag, Last-Modified and Cache-Control headers, and the public PEM certificate(s) from the captured stdout as the body of the message.
    2. If the return code is 4 then send a 404 status code with a ProblemDetail indicating that no such certificateId exists.
    3. If the return code is 8 then send a 204 status code response.
    4. For all other non-zero return codes send a 500 status code with a ProblemDetail indicating there was a certificate management problem.

destroyServerCertificate

  1. Use ${CertMgmt} -c delete ${certificateId}.
    1. If the return code is 0 then send a response to the M1 client with status code 204.
    2. If the return code is 4 then send a 404 status code with a ProblemDetail indicating that no such certificateId exists.
    3. For all other non-zero return codes send a 500 status code with a ProblemDetail indicating there was a certificate management problem.

Providing the certificate and key to the AS

Use the command ${CertMgmt} -c servercert ${certificateId} to retrieve the private key and public certificate(s) from the store as stdout. Use the captured stdout in the M3 interface to provide the certificate to the AS using the UUID certificate ID.

Relevant specifications

devbbc commented 1 year ago

The configured external certificate management command ${CertMgmt} needs to be executed by the AF as an external command.

To execute external commands, the Open5GS framework provides a set of functions such as ogs_proc_create(...), ogs_proc_join(...) and ogs_proc_destroy(...).

Need to check if the external commands inherit the required environment variables from the parent Application Function process, so the next step is to prototype this by calling an external bash script and getting it to print out its environment using e.g. printenv.

devbbc commented 1 year ago

Tested by calling an external bash script that prints out the output of the printenv command. It seems to inherit only the PWD environment variables.

_Edit: Subsequently found a flag ogs_proc_option_inherit_environment that enables external commands to inherit the required environment variables from the parent process._

Then, modified the external bash script to generate a new key by executing openssl command. It generated a new key file. So, it may be possible to execute ${CertMgmt} as an external bash script from Open5GS.

devbbc commented 1 year ago

Started implementing a sample external Certificate Management as an external bash script ${CertMgmt}. It can perform the newcsr operation and if successful outputs the CSR in PEM format on stdout. On error, returns the error code.

With this newcsr operation in place, I started implementing the M1 ServerCertificatesProvisioning API createOrReserveServerCertificate operation. The Application Function can now generate a UUID for the certificate id and can invoke ${CertMgmt} for the newcsr operation.

Tried to test the reservation operation, with request query parameter csr=true passed along with the request header from M1 client. Found that whilst parsing the request header, Open5GS seems to ignore the request query parameter and just passes the provisioning session identifier to the Application Function.

For example, for the M1 client request: curl -H 'User-Agent: AF' -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/6b21fe30-9047-41ed-810c-8d25a766d408?csr=true the request header parsed from Open5GS only has /3gpp-m1/v2/provisioning-sessions/6b21fe30-9047-41ed-810c-8d25a766d408

devbbc commented 1 year ago

The root cause of the above problem is that Open5GS does not extract the request URI query parameter from the parsed output of the yuarel library:

https://github.com/open5gs/open5gs/blob/c0a61fb71eb4f1e6f450a13ecc005af04189a609/lib/sbi/message.c#L782-L791

We need to modify Open5GS to extract and store the query string value in its ogs_sbi_message_t data structure (perhaps as an additional member) so that other functions can access the query string. This may need consultation with @acetcom. What do you think @davidjwbbc?

devbbc commented 1 year ago

Meanwhile, I will continue to implement other M1 Server Certificates Provisioning operations (e.g. creation).

acetcom commented 1 year ago

@devbbc

You can find an example of extraction as below. https://github.com/open5gs/open5gs/blob/main/lib/sbi/nghttp2-server.c#L1050-L1080

Hope it can help you.

Thanks! Sukchan

rjb1000 commented 1 year ago

You can find an example of extraction as below. https://github.com/open5gs/open5gs/blob/main/lib/sbi/nghttp2-server.c#L1050-L1080

@acetcom: Thanks for pointing us to the above code snippet in nghttp2-server.c.

Just so I understand what I am looking at, is this showing that the HTTP/2 server implementation in Open5GS always attempts to parse out the query parameters from the request URL and stores them in request->http.params?

Would you therefore advise @devbbc that he might have better luck interacting with his Application Function using HTTP/2 rather than HTTP/1.1, i.e. by adding the --http2-prior-knowledge command line option to his curl test commands?

devbbc commented 1 year ago

Sample output of the creation operation:

curl -H 'User-Agent: AF' X POST -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/4a29c0b8-923c-41ed-9e06-c97726cece4f/certificates
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> POST /3gpp-m1/v2/provisioning-sessions/4a29c0b8-923c-41ed-9e06-c97726cece4f/certificates HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 0
< Location: /3gpp-m1/v2/provisioning-sessions/4a29c0b8-923c-41ed-9e06-c97726cece4f/certificates/5406b5d2-923c-41ed-9e06-c97726cece4f
< 
* Connection #0 to host 127.0.0.22 left intact

Next operation to implement: retrieveServerCertificate to demonstrate that the creation operation has succeeded.

acetcom commented 1 year ago

@rjb1000

HTTP1.1 is also supporting Query Parameter as below. https://github.com/open5gs/open5gs/blob/main/lib/sbi/mhd-server.c#L511-L513

devbbc commented 1 year ago

@acetcom - Thanks for the pointers and suggestions.

Yes, tested extracting the Query Parameter from both nghttp2 and http/1.1. Had success in both.

Found that the query parameters are placed in http.params and are stored in a hash. The values of the query parameters can then be obtained from this hash.

devbbc commented 1 year ago

Implemented the reservation operation. The sample output shows a response with mime-type application/x-pem-file and status code 200. The Location header is set to the resource path with the UUID.

Note that the query parameter requires csr= rather than just csr. Looks like csr is not stored in the hash without =. Possibly using = as a delimiter to seperate key and value.

curl -H 'User-Agent: AF' -X POST -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/402f9b7e-9619-41ed-ac2d-b9bc113231b4/certificates?csr=

*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> POST /3gpp-m1/v2/provisioning-sessions/402f9b7e-9619-41ed-ac2d-b9bc113231b4/certificates?csr= HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 985
< Content-Type: application/x-pem-file
< Location: /3gpp-m1/v2/provisioning-sessions/402f9b7e-9619-41ed-ac2d-b9bc113231b4/certificates/4b945d74-9619-41ed-ac2d-b9bc113231b4
< 
-----BEGIN CERTIFICATE REQUEST-----
MIICnjCCAYYCAQAwMjELMAkGA1UEBhMCR0IxDzANBgNVBAcMBkxvbmRvbjESMBAG
A1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
ti0a7OXLelTtLa6rlHN90SkhNmsIjPzXy1dMJIJJZiwCbr4J5ccNhm4tHS95z6Hb
6pBLoWU7I9h5CFvR0bhe8oDUTlfPfEwqgCuT1rqaEUe3O1rKEtWLcRvkwsh5Zohv
qjtqRGduuSZ1vSCK24AGb6CrUkoWBtQfiV1OdVhn8H9GdhAHjNWWxFUouGDGmhEw
WtfjIgxq7Ac8Kdj4PSQ9ksH+kpLQ2YbkZnyMFaBGIskZSp5bKMQpvA3+YGLOAwIn
FXo690KLqWGj3c3RwbC2xM4a85e9XLArhvGNhNoshlNAdVLUY6IVTsLJaD0vm5J5
UUC7KXHcFL1xXBOr1aSUdQIDAQABoCcwJQYJKoZIhvcNAQkOMRgwFjAUBgNVHREE
DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAHda9RZhbn4F83xT2VaQ
E+0Z23mD4LeNHpU3v2/FGExX/qrHhT6NKdzRycjfH6mU09PaVv/ocQQlFew1RotH
VNB8/yuOwoWteZ2RMxxko9FdJk3F/zMFQ+ye5aPGFaUAWmtdkNoYZhssHSGJkfrv
rd7pEcRRwFE1T8SD5Wn/Jk9F2A7uid6NTh4V457Xrfs5JCUjIIIYDlEudOwni7mD
9ZEJSvRZpjjm+4Npj7NV7lA41ILozvSBwbsL8E3j9A6PGS6wB2yhMjnmseSqv8rO
4ZVqd8tIUqX7TDzAGeaqovI1epUU2ZdTRn1tejoX8+Ta0cvY6tRokMI3ZeNM3LI8
4BI=
-----END CERTIFICATE REQUEST-----
* Connection #0 to host 127.0.0.22 left intact
devbbc commented 1 year ago

Implemented the retrieveServerCertificate operation. Next operation to implement: destroyServerCertificate.

Sample creation and retrieval operation:

$curl -H 'User-Agent: AF' -X POST -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/a23aeb0e-97c5-41ed-aa8c-1fb8b9d754c4/certificates
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> POST /3gpp-m1/v2/provisioning-sessions/a23aeb0e-97c5-41ed-aa8c-1fb8b9d754c4/certificates HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 0
< Location: /3gpp-m1/v2/provisioning-sessions/a23aeb0e-97c5-41ed-aa8c-1fb8b9d754c4/certificates/bb1cf608-97c5-41ed-aa8c-1fb8b9d754c4
< 
* Connection #0 to host 127.0.0.22 left intact

$ curl -H 'User-Agent: AF' -H 'Content-Type: application/x-pem-file' -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/a23aeb0e-97c5-41ed-aa8c-1fb8b9d754c4/certificates/bb1cf608-97c5-41ed-aa8c-1fb8b9d754c4
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> GET /3gpp-m1/v2/provisioning-sessions/a23aeb0e-97c5-41ed-aa8c-1fb8b9d754c4/certificates/bb1cf608-97c5-41ed-aa8c-1fb8b9d754c4 HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> Content-Type: application/x-pem-file
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 1074
< Content-Type: application/x-pem-file
< 
-----BEGIN CERTIFICATE-----
MIIC6zCCAdMCFDGiduIVfLl3ybWSy3auDKzcWH5hMA0GCSqGSIb3DQEBCwUAMDIx
CzAJBgNVBAYTAkdCMQ8wDQYDVQQHDAZMb25kb24xEjAQBgNVBAMMCWxvY2FsaG9z
dDAeFw0yMzAxMTkwNjUxNDJaFw0yMzA0MTkwNjUxNDJaMDIxCzAJBgNVBAYTAkdC
MQ8wDQYDVQQHDAZMb25kb24xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBALfXWTQq+OZ2gp/D0QYXvlU14GbSM64eknqp
Dmq0SxWjKErUnj+lxWoYJM4Zy6vPBwbw8Fk2jbA8YzF9/Id+QvdnJKraTeJ30Wmp
f7oBbUhvxgEbnRkooxK+i6me7tsVIIiigL9Qj6gugR9Z+ew/bqE/k8uSuWXjM5MQ
S+HTuWfMzHGBOqJAj7EzvBM0X0Ku1qByzHf0Yby8L2nDhlhZB4tjQ+JPXvrIkMFg
FXT9lHNyi4bzCDNBYXmFCkd6EOuf6KY8Xw6nQjpnPhmSrNEvR6kS5cLrK6ngSIMa
73kayxoM2rPfDcbcEqHOom17tpk8x8kfqyfl06p9uGdNyCKK/osCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEADGhS0aKPUadvS+4zEUe5PcwZe3lRTc6qLdKCYUwCR8AS
pBa2kLn6DWqDqGhekiwraMaTxpiOCYyuwiVx+NnTLY2+d72XJ01IYe//cHmKrLwL
RzwcDVm3mIh9QHcIP0jUjXpWYDo0xsbEhm4/1vojSd0bPtgx8WizyZztouSopOnS
vZosxrLFtHv8uTl50ipDsV75mua8+nEhy00lpKAtdD4y7R/8p6eiD3T3pu+2jReJ
/BMb19jI/94KKSGEzg4+OiXw0XpmJWZ7zl1I/577gI2pdGA4Fe/86J5OpA0DDoJy
ztQ8vXC2eIBe9j5t0T8W6jds9WunO6mXKi+KMIu3Sw==
-----END CERTIFICATE-----
* Connection #0 to host 127.0.0.22 left intact
devbbc commented 1 year ago

The function to handle errors relevant to M1 Server Certificates Provisioning API are now handled by the new error functions defined in #37.

devbbc commented 1 year ago

The cache-control header for the M1 Server Certificates Provisioning can be set in two ways:

  1. By the certificate manager.
  2. By the Application Function (fall back mechanism).

Option 2 is implemented. Implementing option 1.

devbbc commented 1 year ago

Implemented option 1 for cache-control as well the response headers of createOrReserveServerCertificates and retrieveServerCertificate inline with #37.

createOrReserveServerCertificates

$  curl -H 'User-Agent: AF' -X POST -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/e11d20ca-ac84-41ed-978b-e1454db573f5/certificates?csr=
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> POST /3gpp-m1/v2/provisioning-sessions/e11d20ca-ac84-41ed-978b-e1454db573f5/certificates?csr= HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 985
< Server: 5GMSdAF-af.localdomain/17.3.0 rt-5gms-application-function/1.1.0
< Cache-Control: max-age=65
< Last-Modified: Tue, 14 Feb 2023 16:31:10 GMT
< ETag: 484cf0212b4a4a6ad060315227b14448bc191a59b0aa1e8f9f3f5bbcb031ecdc
< Content-Type: application/x-pem-file
< Location: /3gpp-m1/v2/provisioning-sessions/e11d20ca-ac84-41ed-978b-e1454db573f5/certificates/fd2b32d4-ac84-41ed-978b-e1454db573f5
< Date: Tue, 14 Feb 2023 16:31:10 GMT
< 
-----BEGIN CERTIFICATE REQUEST-----
MIICnjCCAYYCAQAwMjELMAkGA1UEBhMCR0IxDzANBgNVBAcMBkxvbmRvbjESMBAG
A1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
3IciQDRssZWWhTbzK2v868I8Bri50N11Xv1dE9ylylSjpUyTrYqNMACUwhekEOo+
rF5jUkSRGb+IqMi/VPS53gZNeGyiGf6naTSnP7A77TS9wlvPnuJ2hbgfjPu77iyU
DWiZMaM77WED4cUxq9iMx3i7DfKS82HgKyyrIbafXyKKZFtQNZ7EPL/S5E3JRFjm
/RA/hTr8Pfa8BuI6K9KfoewSgtL+Dl7R2lAt+52mYtH5xoJDmc2DeBqeCJHTat9o
Ja/eYsbhr33NW+7Igqoxg4AS7LJ4g2K3TT56dS+dthpnTTgkdeOsjxxCit5VKO4s
Tg0hDPu4JrAHw6YNNsLC3QIDAQABoCcwJQYJKoZIhvcNAQkOMRgwFjAUBgNVHREE
DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAGj6Vtq624FjHoyQ1xV8
zEAHZOlMUN1Tal3R4Bas/OjjlNKh17HqTARGzj6aOLrYeow3LuHjqWAaz6jtmVcD
Zm1kIShbrwqyQ2ZSD0xrj/J+wYYu87s0S1eJ60+BS8MHldxFU9UY0t7D2iGNl0/G
RvYdxQph4zSVhbckm9suf0IiSf+cLATRLCDe4fddxhx8Nsi5M0p6PVu+wlMrsHRo
w2HIabjeqvhNmJVO4zFwE/gyLK0hsSHV6qqq5kvEQfgFHUKg+viitaM1XuyZpc0B
PFbSrAQmj8WxF5VAHt2qJa5jCU4rty5T5K85L4bgiqTwpTGSspPDyRgbynkC3tzv
OVk=
-----END CERTIFICATE REQUEST-----
* Connection #0 to host 127.0.0.22 left intact
$ curl -H 'User-Agent: AF' -X POST -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/e11d20ca-ac84-41ed-978b-e1454db573f5/certificates
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> POST /3gpp-m1/v2/provisioning-sessions/e11d20ca-ac84-41ed-978b-e1454db573f5/certificates HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 0
< ETag: 3a86c5399e0d45cfda4fd5754af48f2c2d9bd2c5ce8e0671525b6f6c50e37ba5
< Location: /3gpp-m1/v2/provisioning-sessions/e11d20ca-ac84-41ed-978b-e1454db573f5/certificates/42d5c9c0-ac85-41ed-978b-e1454db573f5
< Server: 5GMSdAF-af.localdomain/17.3.0 rt-5gms-application-function/1.1.0
< Cache-Control: max-age=70
< Last-Modified: Tue, 14 Feb 2023 16:33:07 GMT
< Date: Tue, 14 Feb 2023 16:33:07 GMT
< 

retrieveServerCertificate

curl -H 'User-Agent: AF' -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/e11d20ca-ac84-41ed-978b-e1454db573f5/certificates/42d5c9c0-ac85-41ed-978b-e1454db573f5
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> GET /3gpp-m1/v2/provisioning-sessions/e11d20ca-ac84-41ed-978b-e1454db573f5/certificates/42d5c9c0-ac85-41ed-978b-e1454db573f5 HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 1074
< Content-Type: application/x-pem-file
< Server: 5GMSdAF-af.localdomain/17.3.0 rt-5gms-application-function/1.1.0
< Cache-Control: max-age=70
< Last-Modified: Tue, 14 Feb 2023 16:33:07 GMT
< ETag: 3a86c5399e0d45cfda4fd5754af48f2c2d9bd2c5ce8e0671525b6f6c50e37ba5
< Date: Tue, 14 Feb 2023 16:37:51 GMT
< 
-----BEGIN CERTIFICATE-----
MIIC6zCCAdMCFF9Dj2DkDdfxxd0PWvYWYh7hnRsvMA0GCSqGSIb3DQEBCwUAMDIx
CzAJBgNVBAYTAkdCMQ8wDQYDVQQHDAZMb25kb24xEjAQBgNVBAMMCWxvY2FsaG9z
dDAeFw0yMzAyMTQxNjMzMDdaFw0yMzA1MTUxNjMzMDdaMDIxCzAJBgNVBAYTAkdC
MQ8wDQYDVQQHDAZMb25kb24xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAMjpFa8xSDOQuoMffZXh1R57P9QkleiPlPyT
gqB51vFEy+0fA7pqE2op4uoQLbEHOtgvFsHUCIZSjEdNIq/2KGW0WblPbXaAS92i
D1vmJc+fmTp7h6ur+FM0FfhYfFvk1MEeOOSF3Dr5jxW1oGxTCOETfZjIqbIsD7N5
v670CrZa4//gDDuN7Lk3PzdgKaAu3FD4EBPZKFQH/wCpVuorJM1F78ujdQbhGfPI
tr9FJ0X6KNN8YdeRy8y74jx6LqeVFEKWulfARa4jryg2xhs10WDGzG5tRHikJMkd
SxYr2nsFiqd7kvbSI3m9rbLgN8pr9a4ct9eV2w2s6EIj8Ee1masCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEAFXISYmes5ghrBFd9I7vaNKV43fr51akHA7oKdFKCyDXa
+CZC/6fJhniBT08WK2hmCtp+xNlYHDR+GQTXcjB3ZdF3xYanaXHlNLBDZoL0zj2b
qsQb9jpF3/0OsAsJdvE7/XfE3zV6f16rLKGynpGoaf1tX/vCv2Blu5e+L6lX2QXp
phZhxRYMF/L09zxsE+LssrG8B1Q/ucpaRLOVZJxqDV42irUSUrpKAEmzCr8wJvnw
5FSqNdqWeIyb844uRnOU5QSXlAIQJ0ghSRYBXQjYt4DmHAfxXmsmtA7LiVQJ/nD9
UIL+3oG11+wZjDHg6cDaLmHfpol2D00AtbY+Y5refg==
-----END CERTIFICATE-----
* Connection #0 to host 127.0.0.22 left intact

There is a small wrinkle in the server as the code files for M3_ServerCertificatesProvisioning are not being generated by the script. Will look in to this.

davidjwbbc commented 1 year ago

You'll need to add M3_ServerCertificatesProvisioning and M3_ContentHostingProvisioning to the list of default_apis in the src/5gmsaf/generator-5gmsaf script. However there is no content schemas defined in those files so no openapi model files will get created for them.

davidjwbbc commented 1 year ago

Actually isn't it TS26512_M1_ServerCertificatesProvisioning that you are missing for your M1 interface? But again there's no content schemas and therefore no openapi model files generated.

devbbc commented 1 year ago

With a custom mustache template and modifications to the openapi generator scripts by @davidjwbbc , Server header now has info.title and info.version for the Server Certificates Provisioning.

createOrReserveServerCertificates

ubuntu@ogs:~$ curl -H 'User-Agent: AF' -X POST -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/6bf6ba9a-ad5b-41ed-9113-d1fd39fd731e/certificates?csr=
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> POST /3gpp-m1/v2/provisioning-sessions/6bf6ba9a-ad5b-41ed-9113-d1fd39fd731e/certificates?csr= HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 985
< Content-Type: application/x-pem-file
< Location: /3gpp-m1/v2/provisioning-sessions/6bf6ba9a-ad5b-41ed-9113-d1fd39fd731e/certificates/7f6d0642-ad5b-41ed-9113-d1fd39fd731e
< Server: 5GMSdAF-af.localdomain/17.3.0 (info.title=M1_ServerCertificatesProvisioning; info.version=2.0.0) rt-5gms-application-function/1.1.0
< Cache-Control: max-age=70
< Last-Modified: Wed, 15 Feb 2023 18:06:41 GMT
< ETag: f0a43065202fd792b7710bd374540b4583bfe930231353e61c20872c34800b94
< Date: Wed, 15 Feb 2023 18:06:41 GMT
< 
-----BEGIN CERTIFICATE REQUEST-----
MIICnjCCAYYCAQAwMjELMAkGA1UEBhMCR0IxDzANBgNVBAcMBkxvbmRvbjESMBAG
A1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
tEF/O8Iw9bAFh6tDROvzOpoeOHR/pfkPixsr5AqX8FvrLbRtKRPYzJN4j4/VtEbM
4Oe3TWRJr4+CgiOlAaONgY/hVSH00uxaJYA980E5rdGwKmvgSGync6H3pf/kaScF
BiDSFEEJohfWwgcw808I0ewxjrquJ6Bp11+BuIzzWR/OHlh9Vo0Ub/ARS1XEKS0+
FEGFxhAPXuoJQzJ2mVp1OnZJd0Rwx8vvJXmw8x/fzZ4jCwOEbVPRo631zBPc/PbD
kvUGHpDT9d5ZR4qbpq+YVlsfHzG0SS3FcH7fkHaigHPWBdnM6z+z8VjC8T+hqpDr
M5rQ59FRhYJfleQeuQOxDQIDAQABoCcwJQYJKoZIhvcNAQkOMRgwFjAUBgNVHREE
DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAGx8Bi1IRx2gJQkRiXVk
MAr3UVC6g/ekOVRrfDwIBfoDBS7+Oi1dprHKgJ9oAE3D+nD5nsjfJWgx7HAOblUx
AYc9fafRMKRKgKo4PcWRMuGgQHgv0Un87CtLMjufYNbzfFLv9eVkkFbbre7r3U6i
PtCzDTRdh00r8I481tGVNE7eOuSxkQHXCEdnHW2a6g6dcAhQ70CRf46n1vmsS6hv
5MBVBsonZC43PmZ2QUJMAzL99PDcSHcc7KDFp9SftPAOSabn2AjFWOTI1qM9Cgek
4CCYFn15BRJlAv+Gx7TKcZ90wOlw7+AbMSHQuD1fLTS2hYP61x1NDXL4gxqpOQzT
36I=
-----END CERTIFICATE REQUEST-----
* Connection #0 to host 127.0.0.22 left intact
$ curl -H 'User-Agent: AF' -X POST -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/6bf6ba9a-ad5b-41ed-9113-d1fd39fd731e/certificates
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> POST /3gpp-m1/v2/provisioning-sessions/6bf6ba9a-ad5b-41ed-9113-d1fd39fd731e/certificates HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 0
< Server: 5GMSdAF-af.localdomain/17.3.0 (info.title=M1_ServerCertificatesProvisioning; info.version=2.0.0) rt-5gms-application-function/1.1.0
< Cache-Control: max-age=70
< Last-Modified: Wed, 15 Feb 2023 18:09:54 GMT
< ETag: 50b46c75aa32f479068a2b64258e31ba50d6be8ff75118402daab9c4be7a7549
< Location: /3gpp-m1/v2/provisioning-sessions/6bf6ba9a-ad5b-41ed-9113-d1fd39fd731e/certificates/f289287c-ad5b-41ed-9113-d1fd39fd731e
< Date: Wed, 15 Feb 2023 18:09:54 GMT
< 
* Connection #0 to host 127.0.0.22 left intact

retrieveServerCertificate

$ curl -H 'User-Agent: AF' -v http://127.0.0.22:7777/3gpp-m1/v2/provisioning-sessions/6bf6ba9a-ad5b-41ed-9113-d1fd39fd731e/certificates/f289287c-ad5b-41ed-9113-d1fd39fd731e
*   Trying 127.0.0.22:7777...
* TCP_NODELAY set
* Connected to 127.0.0.22 (127.0.0.22) port 7777 (#0)
> GET /3gpp-m1/v2/provisioning-sessions/6bf6ba9a-ad5b-41ed-9113-d1fd39fd731e/certificates/f289287c-ad5b-41ed-9113-d1fd39fd731e HTTP/1.1
> Host: 127.0.0.22:7777
> Accept: */*
> User-Agent: AF
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 1074
< Content-Type: application/x-pem-file
< Server: 5GMSdAF-af.localdomain/17.3.0 (info.title=M1_ServerCertificatesProvisioning; info.version=2.0.0) rt-5gms-application-function/1.1.0
< Cache-Control: max-age=70
< Last-Modified: Wed, 15 Feb 2023 18:09:54 GMT
< ETag: 50b46c75aa32f479068a2b64258e31ba50d6be8ff75118402daab9c4be7a7549
< Date: Wed, 15 Feb 2023 18:13:35 GMT
< 
-----BEGIN CERTIFICATE-----
MIIC6zCCAdMCFHskCUPmt3OTZpne/FoDwZEDZEckMA0GCSqGSIb3DQEBCwUAMDIx
CzAJBgNVBAYTAkdCMQ8wDQYDVQQHDAZMb25kb24xEjAQBgNVBAMMCWxvY2FsaG9z
dDAeFw0yMzAyMTUxODA5NTRaFw0yMzA1MTYxODA5NTRaMDIxCzAJBgNVBAYTAkdC
MQ8wDQYDVQQHDAZMb25kb24xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAK2NPfrYuVoTwHx9ExVicXSUeVnUnWHAgvo7
PRgi2kMqG0/pwtD+uygpf9i0JAT7gsEIGUFuvV3TqWzE+Mkf9+2QpBsCG92EjzCJ
2uiloE15k3Kp+x4HTW6uVnIfIgjrwHl05JUnFek/X6D+BF8SQ1D8w8F0EhWEEkOJ
5rlAHwXHw3Zo1ZbuCIm09WDj2Ri128T4JafhSPSrGHM/mo5qab8VTMqAmp7ulZL5
iUFzPS37REW5Yak3YJ/tCUIQt7UX7+kTvfo9n653qY129aNJ8o3D6zK3DPoBYzY7
Iy683Vx8lX3wvHIBC4zHiuEw3zKzBo9FC/Eq/78R/4VBgWUM/UcCAwEAATANBgkq
hkiG9w0BAQsFAAOCAQEArdpH7SkdHacXd0nm4RvPgnmvxh1aQkdZt7qzfOA0pgGM
qjWOkSzCe3wkivWPFS5WF59jGfAcUPRGwL7n904sDIWH+HFLOqQrNgmKrWlt5Q/5
YR38LfaE8+IGaw/y4FxsPRD663sQuYJyTkv+neuevWRWK47KsLlRc0yaTjRf7nth
7mZQfyvY+wqf2XM4J3YlpCGijMjZidtVyUSfuxkXxQQP5VSynGtWcagepbBTnuky
oU614HmKA3b1QJD55gnwQ3e6HUFUMadgGDBOPyGwLzO7CnzJSTNwIElJSS5Hmal/
wd8ilUPmd3RgVxC6M+M3AgIwdUA96SutY5xhtDt3Hg==
-----END CERTIFICATE-----
* Connection #0 to host 127.0.0.22 left intact
davidjwbbc commented 1 year ago

The use of the certificate manager script when sending the certificate and key to the AS was missing, the code was still trying to load this from a local file.

I've added a server_cert_get_servercert() to do the servercert operation with the CertMgr script and use the result of that in the M3 message.

davidjwbbc commented 1 year ago

Also fixed an issue where the external process calls to the CertMgr would eventually run out of internal ogs_proc_t structures to use by dynamically allocating and freeing this structure.

davidjwbbc commented 1 year ago

The retrieveServerCertificate M1 request returns a 500 error when the certificate has been reserved but not uploaded, it should return 204. This is my fault as I'd put that response under "deleteServerCertificate" in the main text of this issue rather than "retrieveServerCertificate" where it should have been. This has now been corrected, but the corresponding alteration to the code needs to be made too.

devbbc commented 1 year ago

Modified the AF to return 204 for the retrieveServerCertificate M1 request when the certificate has been reserved but not uploaded,

davidjwbbc commented 1 year ago

@devbbc, your code changes threw away previous bug fixes and code improvements due to an incorrectly handled conflict in git. Please revise your code changes to include the bug fixes and code improvements from the previous version.

davidjwbbc commented 1 year ago

Tested the new code and this now looks good. Pushed to development branch for release candidate in PR #53, closing this issue.