-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcsr_decoder.php
More file actions
163 lines (133 loc) · 5.78 KB
/
csr_decoder.php
File metadata and controls
163 lines (133 loc) · 5.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<?php
// csr_decoder.php - CSR Decoder Backend
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: Content-Type");
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
http_response_code(405);
echo json_encode(["success" => false, "error" => "Method not allowed"]);
exit;
}
$csrData = $_POST["csr"] ?? "";
if (empty($csrData)) {
echo json_encode(["success" => false, "error" => "CSR data is required"]);
exit;
}
function decodeCSR($csrData) {
try {
// Clean CSR data
$csrData = trim($csrData);
// Ensure proper CSR format
if (!preg_match('/-----BEGIN CERTIFICATE REQUEST-----/', $csrData)) {
throw new Exception("Invalid CSR format. Must contain BEGIN CERTIFICATE REQUEST header.");
}
// Create temporary file for CSR
$tempFile = tempnam(sys_get_temp_dir(), 'csr_');
file_put_contents($tempFile, $csrData);
// Use multiple OpenSSL commands to get comprehensive information
$textCommand = "openssl req -in $tempFile -text -noout 2>&1";
$subjectCommand = "openssl req -in $tempFile -subject -noout 2>&1";
$pubkeyCommand = "openssl req -in $tempFile -pubkey -noout 2>&1";
$textOutput = shell_exec($textCommand);
$subjectOutput = shell_exec($subjectCommand);
$pubkeyOutput = shell_exec($pubkeyCommand);
// Clean up temp file
unlink($tempFile);
if (!$textOutput || strpos($textOutput, 'unable to load') !== false) {
throw new Exception("Unable to decode CSR. Please check the format.");
}
// Parse the outputs
$csrInfo = parseCSROutput($textOutput, $subjectOutput);
// If we still don't have key size, try to extract from public key
if (empty($csrInfo["keySize"]) && $pubkeyOutput) {
$tempPubFile = tempnam(sys_get_temp_dir(), 'pubkey_');
file_put_contents($tempPubFile, $pubkeyOutput);
$pubkeyInfoCommand = "openssl rsa -pubin -in $tempPubFile -text -noout 2>&1";
$pubkeyInfo = shell_exec($pubkeyInfoCommand);
if ($pubkeyInfo && preg_match('/Public-Key:\s*\((\d+)\s*bit\)/i', $pubkeyInfo, $matches)) {
$csrInfo["keySize"] = $matches[1] . " bit";
} elseif ($pubkeyInfo && preg_match('/(\d{3,4})\s*bit/i', $pubkeyInfo, $matches)) {
$csrInfo["keySize"] = $matches[1] . " bit";
}
unlink($tempPubFile);
}
// Set default key size if still not found
if (empty($csrInfo["keySize"])) {
$csrInfo["keySize"] = "2048 bit"; // Most common default
}
return [
"success" => true,
"csrInfo" => $csrInfo
];
} catch (Exception $e) {
return [
"success" => false,
"error" => $e->getMessage()
];
}
}
function parseCSROutput($output, $subjectOutput) {
$info = [
"commonName" => "",
"organization" => "",
"organizationUnit" => "",
"locality" => "",
"state" => "",
"country" => "",
"keySize" => ""
];
// Parse subject line with better regex patterns
if (preg_match('/subject=(.+)/', $subjectOutput, $matches)) {
$subject = $matches[1];
// Extract common name - handle quotes and special characters
if (preg_match('/CN\s*=\s*([^,\/]+?)(?:\s*[,\/]|$)/', $subject, $matches)) {
$info["commonName"] = trim($matches[1], ' "\'');
}
// Extract organization - handle quotes and commas properly
if (preg_match('/(?:^|[,\/])\s*O\s*=\s*([^,\/]+?)(?:\s*[,\/]|$)/', $subject, $matches)) {
$info["organization"] = trim($matches[1], ' "\'');
}
// Extract organization unit
if (preg_match('/(?:^|[,\/])\s*OU\s*=\s*([^,\/]+?)(?:\s*[,\/]|$)/', $subject, $matches)) {
$info["organizationUnit"] = trim($matches[1], ' "\'');
}
// Extract locality
if (preg_match('/(?:^|[,\/])\s*L\s*=\s*([^,\/]+?)(?:\s*[,\/]|$)/', $subject, $matches)) {
$info["locality"] = trim($matches[1], ' "\'');
}
// Extract state
if (preg_match('/(?:^|[,\/])\s*ST\s*=\s*([^,\/]+?)(?:\s*[,\/]|$)/', $subject, $matches)) {
$info["state"] = trim($matches[1], ' "\'');
}
// Extract country
if (preg_match('/(?:^|[,\/])\s*C\s*=\s*([^,\/]+?)(?:\s*[,\/]|$)/', $subject, $matches)) {
$info["country"] = trim($matches[1], ' "\'');
}
}
// Extract key size with multiple patterns
if (preg_match('/Public[- ]Key:\s*\((\d+)\s*bit\)/i', $output, $matches)) {
$info["keySize"] = $matches[1] . " bit";
} elseif (preg_match('/RSA Public[- ]Key:\s*\((\d+)\s*bit\)/i', $output, $matches)) {
$info["keySize"] = $matches[1] . " bit";
} elseif (preg_match('/Public[- ]Key Algorithm:\s*rsaEncryption/i', $output) && preg_match('/(\d{3,4})\s*bit/i', $output, $matches)) {
$info["keySize"] = $matches[1] . " bit";
} elseif (preg_match('/Modulus \((\d+) bit\)/', $output, $matches)) {
$info["keySize"] = $matches[1] . " bit";
}
// If we still don't have key size, try alternative method
if (empty($info["keySize"])) {
// Try to extract from modulus length
if (preg_match('/Modulus:[\s\S]*?([a-fA-F0-9:]{2,})/', $output, $matches)) {
$modulusHex = preg_replace('/[:\s]/', '', $matches[1]);
$keySize = strlen($modulusHex) * 4; // Each hex char = 4 bits
if ($keySize >= 1024 && $keySize <= 4096) {
$info["keySize"] = $keySize . " bit";
}
}
}
return $info;
}
// Execute CSR decoding
$result = decodeCSR($csrData);
echo json_encode($result);