Commit 76161670 authored by Jorge Moratinos's avatar Jorge Moratinos
Browse files

Modified way to generate certificate for CCF, using as CN the CCF_ID

parent dedfd76c
Loading
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -12,8 +12,8 @@ export CAPIF_HTTPS_PORT=443
export MONGO_EXPRESS_CCF_PORT=8081

# Mock server variables
export MOCK_SERVER_INTERNAL_HOSTNAME=mock-server
export MOCK_SERVER_EXTERNAL_HOSTNAME=mock-server
export MOCK_SERVER_INTERNAL_HOSTNAME=mock-server-a
export MOCK_SERVER_EXTERNAL_HOSTNAME=mock-server-a
export MOCK_SERVER_INTERNAL_PORT=9100
export MOCK_SERVER_EXTERNAL_PORT=9100
# Register hostname and port
+3 −3
Original line number Diff line number Diff line
@@ -13,9 +13,9 @@ export CAPIF_HTTPS_PORT=1443
export MONGO_EXPRESS_CCF_PORT=8181

# Mock server variables
export MOCK_SERVER_INTERNAL_HOSTNAME=mock-server
export MOCK_SERVER_EXTERNAL_HOSTNAME=mock-server
export MOCK_SERVER_INTERNAL_PORT=9100
export MOCK_SERVER_INTERNAL_HOSTNAME=mock-server-b
export MOCK_SERVER_EXTERNAL_HOSTNAME=mock-server-b
export MOCK_SERVER_INTERNAL_PORT=9200
export MOCK_SERVER_EXTERNAL_PORT=9200

# Register hostname and port
+27 −10
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ from datetime import datetime
import requests
import json

from flask import current_app
from flask import current_app, Response
# from pymongo import ReturnDocument

from db.db import get_mongo
@@ -71,16 +71,33 @@ class CapifDomainOperations(Resource):
            'Content-Type': 'application/json'
        }

        try:
            response = requests.request("POST", url, headers=headers, data=payload,
                                        cert=('certs/server.crt', 'certs/server.key'),
                                        verify='certs/ca.crt')
        except requests.exceptions.RequestException as exc:
            detail = "Error calling interconnection endpoint: {}".format(str(exc))
            current_app.logger.error(detail)
            return internal_server_error(detail=detail, cause="REQUEST_FAILURE")

        try:
            inter_ccf = response.json()
        except ValueError:
            inter_ccf = response.text

        current_app.logger.debug(inter_ccf)

        if response.status_code == 201 or response.status_code == 200:
        if response.status_code in (200, 201):
            if isinstance(inter_ccf, dict):
                interconnected_col.insert_one(inter_ccf)

                ccfinstancedetails_new = CcfInstanceDetails().from_dict(dict_to_camel_case(inter_ccf))
        res = make_response(object=ccfinstancedetails_new, status=response.status_code)
        return res
                return make_response(object=ccfinstancedetails_new, status=response.status_code)

            # If upstream returns a non-JSON success body, propagate it as-is.
            return Response(response.text, status=response.status_code, mimetype="application/json")

        remote_mimetype = response.headers.get("Content-Type", "application/problem+json").split(";")[0]
        if isinstance(inter_ccf, (dict, list)):
            return Response(json.dumps(inter_ccf), status=response.status_code, mimetype=remote_mimetype)

        return Response(response.text, status=response.status_code, mimetype=remote_mimetype)
+298 −0
Original line number Diff line number Diff line
{
  "info": {
    "_postman_id": "9f3f0f74-53c2-4fdc-b6b4-6c895d2486b9",
    "name": "CCF Interconnection API",
    "description": "Postman collection for CCF Interconnection API endpoints.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Create Interconnection - POST /connect",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"caRoot\": \"-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----\",\n  \"publicKey\": \"-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----\",\n  \"ccfId\": \"ccf-001\",\n  \"dstProvDom\": \"provider-b.example.com\"\n}"
        },
        "url": {
          "raw": "{{baseUrl}}/connect",
          "host": [
            "{{baseUrl}}"
          ],
          "path": [
            "connect"
          ]
        },
        "description": "Create a new interconnection between CCFs."
      },
      "response": [
        {
          "name": "201 Interconnection succeeded",
          "originalRequest": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"caRoot\": \"-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----\",\n  \"publicKey\": \"-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----\",\n  \"ccfId\": \"ccf-001\",\n  \"dstProvDom\": \"provider-b.example.com\"\n}"
            },
            "url": {
              "raw": "{{baseUrl}}/connect",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "connect"
              ]
            }
          },
          "status": "Created",
          "code": 201,
          "_postman_previewlanguage": "json",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"caRoot\": \"-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----\",\n  \"publicKey\": \"-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----\",\n  \"ccfId\": \"ccf-001\",\n  \"dstProvDom\": \"provider-b.example.com\"\n}"
        },
        {
          "name": "400 Bad Request",
          "originalRequest": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/connect",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "connect"
              ]
            }
          },
          "status": "Bad Request",
          "code": 400,
          "_postman_previewlanguage": "json",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/problem+json"
            }
          ],
          "body": "{\n  \"type\": \"https://example.com/problems/invalid-request\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"detail\": \"Request body contains invalid or missing parameters.\",\n  \"instance\": \"/interconnection/connect\",\n  \"cause\": \"MANDATORY_IE_MISSING\",\n  \"invalidParams\": [\n    {\n      \"param\": \"/ccfId\",\n      \"reason\": \"is required\"\n    },\n    {\n      \"param\": \"/publicKey\",\n      \"reason\": \"must be a valid PEM public key\"\n    }\n  ],\n  \"supportedFeatures\": \"1F\"\n}"
        },
        {
          "name": "401 Unauthorized",
          "originalRequest": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/connect",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "connect"
              ]
            }
          },
          "status": "Unauthorized",
          "code": 401,
          "_postman_previewlanguage": "json",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/problem+json"
            }
          ],
          "body": "{\n  \"type\": \"https://example.com/problems/unauthorized\",\n  \"title\": \"Unauthorized\",\n  \"status\": 401,\n  \"detail\": \"Missing or invalid authentication credentials.\",\n  \"instance\": \"/interconnection/connect\",\n  \"cause\": \"INVALID_TOKEN\"\n}"
        },
        {
          "name": "403 Forbidden",
          "originalRequest": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/connect",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "connect"
              ]
            }
          },
          "status": "Forbidden",
          "code": 403,
          "_postman_previewlanguage": "json",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/problem+json"
            }
          ],
          "body": "{\n  \"type\": \"https://example.com/problems/forbidden\",\n  \"title\": \"Forbidden\",\n  \"status\": 403,\n  \"detail\": \"The client is not allowed to perform this operation.\",\n  \"instance\": \"/interconnection/connect\",\n  \"cause\": \"INSUFFICIENT_SCOPE\"\n}"
        },
        {
          "name": "404 Not Found",
          "originalRequest": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/connect",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "connect"
              ]
            }
          },
          "status": "Not Found",
          "code": 404,
          "_postman_previewlanguage": "json",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/problem+json"
            }
          ],
          "body": "{\n  \"type\": \"https://example.com/problems/not-found\",\n  \"title\": \"Not Found\",\n  \"status\": 404,\n  \"detail\": \"The target resource was not found.\",\n  \"instance\": \"/interconnection/connect\",\n  \"cause\": \"RESOURCE_NOT_FOUND\"\n}"
        }
      ]
    },
    {
      "name": "Interconnect Request - POST /interconnect",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"dstProvDom\": \"provider-b.example.com\"\n}"
        },
        "url": {
          "raw": "{{baseUrl}}/interconnect",
          "host": [
            "{{baseUrl}}"
          ],
          "path": [
            "interconnect"
          ]
        },
        "description": "Send a new interconnection request to another CAPIF domain."
      },
      "response": [
        {
          "name": "201 Interconnection request succeeded",
          "originalRequest": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"dstProvDom\": \"provider-b.example.com\"\n}"
            },
            "url": {
              "raw": "{{baseUrl}}/interconnect",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "interconnect"
              ]
            }
          },
          "status": "Created",
          "code": 201,
          "_postman_previewlanguage": "json",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"dstProvDom\": \"provider-b.example.com\"\n}"
        },
        {
          "name": "400 Bad Request",
          "originalRequest": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/interconnect",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "interconnect"
              ]
            }
          },
          "status": "Bad Request",
          "code": 400,
          "_postman_previewlanguage": "json",
          "header": [
            {
              "key": "Content-Type",
              "value": "application/problem+json"
            }
          ],
          "body": "{\n  \"type\": \"https://example.com/problems/invalid-request\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"detail\": \"dstProvDom is missing or invalid.\",\n  \"instance\": \"/interconnection/interconnect\",\n  \"cause\": \"MANDATORY_IE_MISSING\",\n  \"invalidParams\": [\n    {\n      \"param\": \"/dstProvDom\",\n      \"reason\": \"is required\"\n    }\n  ]\n}"
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "http://localhost:8080/interconnection",
      "type": "string"
    }
  ]
}
+3 −3
Original line number Diff line number Diff line
@@ -81,11 +81,11 @@ generate_server_key_and_sign() {
        
        echo "[STEP 3] Server certificate not found"
        echo "[STEP 3] Generating CSR for CAPIF service"
                echo "[INFO] Common Name (CN): CCF$CAPIF_HOSTNAME"
                echo "[INFO] Common Name (CN): $CCF_ID"

        # Generate CSR using the previously generated server.key
        openssl req -new -key $CERTS_FOLDER/server.key \
            -subj "/CN=CCF$CAPIF_HOSTNAME" \
            -subj "/CN=$CCF_ID" \
            -addext "subjectAltName=DNS:$CAPIF_HOSTNAME" \
            -out $CERTS_FOLDER/server.csr

@@ -106,7 +106,7 @@ generate_server_key_and_sign() {
            # POST /v1/pki_int/sign/my-ca intermediate's endpoint to sign the CSR
            SIGN_RESPONSE=$(curl -s -X POST \
                -H "X-Vault-Token: $VAULT_TOKEN" \
                -d "{\"csr\":\"$CSR_CONTENT\",\"format\":\"pem_bundle\",\"common_name\":\"CCF$CAPIF_HOSTNAME\",\"alt_names\":\"$CAPIF_HOSTNAME\"}" \
                -d "{\"csr\":\"$CSR_CONTENT\",\"format\":\"pem_bundle\",\"common_name\":\"$CCF_ID\",\"alt_names\":\"$CAPIF_HOSTNAME\"}" \
                "$VAULT_ADDR/v1/pki_int/sign/my-ca")

            # SIGN_RESPONSE; return a PEM bundle format with the signed certificate + intermediate certificate chain (but without the root).