Closed rjb1000 closed 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
.
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.
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
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:
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?
Meanwhile, I will continue to implement other M1 Server Certificates Provisioning operations (e.g. creation).
@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
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?
$CertMgmt
bash
script to list the available certificates in the certificate store.M1 ServerCertificatesProvisioning API
as in the above design.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.
@rjb1000
HTTP1.1 is also supporting Query Parameter as below. https://github.com/open5gs/open5gs/blob/main/lib/sbi/mhd-server.c#L511-L513
@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.
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
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
The function to handle errors relevant to M1 Server Certificates Provisioning API are now handled by the new error functions defined in #37.
The cache-control
header for the M1 Server Certificates Provisioning can be set in two ways:
Option 2 is implemented. Implementing option 1.
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.
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.
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.
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
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.
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.
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.
Modified the AF to return 204 for the retrieveServerCertificate M1 request when the certificate has been reserved but not uploaded,
@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.
Tested the new code and this now looks good. Pushed to development branch for release candidate in PR #53, closing this issue.
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:
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:
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.
ETag
s 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
andCache-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 altNames 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 altNames 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 aCache-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 anewcsr
certificate that has not been uploaded usingsetcert
, 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 ids are given then the list is limited to those ids, if one or more of those ids 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.:
The example shows:
newcsr
, that is still awaiting a certificate upload viasetcert
.msas-test
msas01
msas01
msas01
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
istruepresent then this is a reservation operation; otherwise it a creation operation.reservation
${CertMgmt} -c newcsr ${uuid} ${canonicalDomainName}
(if canonicalDomainName is not known at this point use "localhost") and capture the stdout.Etag
,Last-Modified
andCache-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. TheLocation
header shall be used to return the resource path with the chosen UUID.creation
${CertMgmt} -c list
and look for a subject with aCN
field of${canonicalDomainName}
in the stdout.Location
header and respond with a 200 status code. No further processing is required for this request.${CertMgmt} -c newcert ${uuid} ${canonicalDomainName}
.Location
header set to the resource path including the generated UUID, there is no body data with this response.uploadServerCertificate
${CertMgmt} -c setcert ${certificateId}
and push the request body to stdin.retrieveServerCertificate
${CertMgmt} -c publiccert ${certificateId}
and capture the stdout.ETag
,Last-Modified
andCache-Control
headers, and the public PEM certificate(s) from the captured stdout as the body of the message.destroyServerCertificate
${CertMgmt} -c delete ${certificateId}
.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