SHT30 온습도 모니터링 시스템 전체 소스(서버 PHP, STM32 펌웨어, SQL, 테스트). 전체 코드리뷰에서 도출된 보안 하드닝 10건 반영: - 요청 서명 HMAC-SHA256 전환(펌웨어 sig.c/서버 config.php/호스트 패리티 동시) - 재전송 방어 + 기본 API_KEY fail-closed + 디바이스 문자열 정제(api/sensor_data.php) - 오프라인 SMS 중복 발송 경합 제거(cron_heartbeat.php, 원자적 선점) - CSV 수식 주입 방지(monthly_report.php), 감사로그 회전 락(retention_cleanup.php) - 브루트포스 카운터 원자화(login.php), 예시 TOTP 비밀키 무효화, 마이그레이션 멱등화 _backup/(하드코딩 실 비밀값 포함)·config.local.php·런타임 상태는 .gitignore 제외.
113 lines
4.3 KiB
PowerShell
113 lines
4.3 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
PEM 인증서 파일로부터 firmware/certs/server_ca.c 를 재생성한다.
|
|
|
|
.DESCRIPTION
|
|
Cafe24 서버 루트 CA(필요 시 intermediate+root 를 연결한 체인) PEM 을 읽어,
|
|
mbedTLS 가 그대로 파싱할 수 있는 C 문자열 리터럴 형태로 server_ca.c 에 임베드한다.
|
|
|
|
- 각 PEM 라인을 "....\n" C 리터럴로 변환(끝의 종결 NUL 은 sizeof 에 포함).
|
|
- SERVER_CA_PEM_LEN = sizeof(SERVER_CA_PEM) 로 정의(NUL 포함 → mbedTLS 요구).
|
|
- 폐쇄망: 이 스크립트는 *빌드 머신*에서만 실행. 타깃은 결과 .c 만 컴파일.
|
|
|
|
.PARAMETER PemPath
|
|
입력 PEM 파일 경로(.pem/.crt). 하나 이상의 -----BEGIN CERTIFICATE----- 블록 포함.
|
|
|
|
.PARAMETER OutPath
|
|
출력 C 파일 경로. 기본값: 이 스크립트와 같은 폴더의 server_ca.c
|
|
|
|
.EXAMPLE
|
|
./gen_ca_header.ps1 -PemPath cafe24_root.pem
|
|
|
|
.EXAMPLE
|
|
# 체인 추출 → 헤더 생성 (한 번에)
|
|
openssl s_client -showcerts -connect your-domain.example:443 -servername your-domain.example </dev/null `
|
|
| openssl x509 -out cafe24_root.pem
|
|
./gen_ca_header.ps1 -PemPath cafe24_root.pem
|
|
|
|
.NOTES
|
|
위험 R3(docs/stm32f407_migration_plan.md): 인증서 만료 시 펌웨어 재빌드/재배포 필요.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true, Position = 0)]
|
|
[string]$PemPath,
|
|
|
|
[Parameter(Position = 1)]
|
|
[string]$OutPath = (Join-Path $PSScriptRoot 'server_ca.c')
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# --- 입력 검증 ----------------------------------------------------------------
|
|
if (-not (Test-Path -LiteralPath $PemPath)) {
|
|
throw "PEM 파일을 찾을 수 없습니다: $PemPath"
|
|
}
|
|
|
|
# CRLF/CR 을 LF 로 정규화하고 라인 분해. 빈 끝줄은 제거.
|
|
$raw = Get-Content -LiteralPath $PemPath -Raw
|
|
$normalized = $raw -replace "`r`n", "`n" -replace "`r", "`n"
|
|
$lines = $normalized -split "`n"
|
|
|
|
# 최소한 BEGIN/END CERTIFICATE 마커가 있어야 한다.
|
|
if (-not ($normalized -match '-----BEGIN CERTIFICATE-----')) {
|
|
throw "유효한 PEM 인증서 블록(-----BEGIN CERTIFICATE-----)이 없습니다: $PemPath"
|
|
}
|
|
if (-not ($normalized -match '-----END CERTIFICATE-----')) {
|
|
throw "PEM 종료 마커(-----END CERTIFICATE-----)가 없습니다: $PemPath"
|
|
}
|
|
|
|
# 인증서 블록 개수(intermediate+root 연결이면 2개 이상).
|
|
$certCount = ([regex]::Matches($normalized, '-----BEGIN CERTIFICATE-----')).Count
|
|
|
|
# --- C 문자열 리터럴로 변환 ---------------------------------------------------
|
|
# 후행 빈 라인 제거(마지막 -----END----- 뒤의 공백 라인).
|
|
$body = New-Object System.Collections.Generic.List[string]
|
|
foreach ($line in $lines) {
|
|
$body.Add($line) | Out-Null
|
|
}
|
|
while ($body.Count -gt 0 -and [string]::IsNullOrEmpty($body[$body.Count - 1])) {
|
|
$body.RemoveAt($body.Count - 1)
|
|
}
|
|
|
|
# 각 라인을 C escape: 백슬래시/큰따옴표 이스케이프 후 "...\n" 형태로.
|
|
$escapedLines = foreach ($line in $body) {
|
|
$esc = $line -replace '\\', '\\' -replace '"', '\"'
|
|
' "' + $esc + '\n"'
|
|
}
|
|
|
|
$generatedAt = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss zzz')
|
|
$pemFileName = Split-Path -Leaf $PemPath
|
|
|
|
$header = @"
|
|
/* =============================================================================
|
|
* server_ca.c - 서버 루트 CA 인증서 (PEM, flash 임베드) [자동 생성]
|
|
*
|
|
* gen_ca_header.ps1 로 자동 생성됨. 직접 편집하지 말 것.
|
|
* source PEM : $pemFileName
|
|
* 생성 시각 : $generatedAt
|
|
* 인증서 블록: $certCount 개
|
|
*
|
|
* mbedTLS PEM 요구사항: SERVER_CA_PEM_LEN 은 종결 NUL 을 포함해야 한다
|
|
* → sizeof(SERVER_CA_PEM) 사용.
|
|
* 위험 R3: 인증서 만료/교체 시 이 파일 재생성 + 펌웨어 재배포 필요.
|
|
* ===========================================================================*/
|
|
#include "server_ca.h"
|
|
|
|
const char SERVER_CA_PEM[] =
|
|
"@
|
|
|
|
$footer = @"
|
|
;
|
|
|
|
/* 길이: 종결 NUL 포함(mbedTLS PEM 요구). */
|
|
const unsigned int SERVER_CA_PEM_LEN = sizeof(SERVER_CA_PEM);
|
|
"@
|
|
|
|
$content = $header + "`n" + ($escapedLines -join "`n") + $footer + "`n"
|
|
|
|
# UTF-8 (BOM 없음) 로 기록 — arm-none-eabi-gcc 가 깔끔히 읽도록.
|
|
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
|
|
[System.IO.File]::WriteAllText($OutPath, $content, $utf8NoBom)
|
|
|
|
Write-Host "[OK] $OutPath 생성 완료 (인증서 블록 $certCount 개, source: $pemFileName)"
|