var forge=require("./forge");require("./util");var pem=module.exports=forge.pem=forge.pem||{};function foldHeader(e){for(var r=e.name+": ",n=[],o=function(e,r){return" "+r},a=0;a<e.values.length;++a)n.push(e.values[a].replace(/^(\S+\r\n)/,o));r+=n.join(",")+"\r\n";for(var t=0,s=-1,a=0;a<r.length;++a,++t)if(t>65&&-1!==s){var l=r[s];","===l?(++s,r=r.substr(0,s)+"\r\n "+r.substr(s)):r=r.substr(0,s)+"\r\n"+l+r.substr(s+1),t=a-s-1,s=-1,++a}else(" "===r[a]||"	"===r[a]||","===r[a])&&(s=a);return r}function ltrim(e){return e.replace(/^\s+/,"")}pem.encode=function(e,r){r=r||{};var n,o="-----BEGIN "+e.type+"-----\r\n";if(e.procType&&(o+=foldHeader(n={name:"Proc-Type",values:[String(e.procType.version),e.procType.type]})),e.contentDomain&&(o+=foldHeader(n={name:"Content-Domain",values:[e.contentDomain]})),e.dekInfo&&(n={name:"DEK-Info",values:[e.dekInfo.algorithm]},e.dekInfo.parameters&&n.values.push(e.dekInfo.parameters),o+=foldHeader(n)),e.headers)for(var a=0;a<e.headers.length;++a)o+=foldHeader(e.headers[a]);return e.procType&&(o+="\r\n"),o+=forge.util.encode64(e.body,r.maxline||64)+"\r\n",o+="-----END "+e.type+"-----\r\n"},pem.decode=function(e){for(var r,n=[],o=/\s*-----BEGIN ([A-Z0-9- ]+)-----\r?\n?([\x21-\x7e\s]+?(?:\r?\n\r?\n))?([:A-Za-z0-9+\/=\s]+?)-----END \1-----/g,a=/([\x21-\x7e]+):\s*([\x21-\x7e\s^:]+)/,t=/\r?\n/;r=o.exec(e);){var s=r[1];"NEW CERTIFICATE REQUEST"===s&&(s="CERTIFICATE REQUEST");var l={type:s,procType:null,contentDomain:null,dekInfo:null,headers:[],body:forge.util.decode64(r[3])};if(n.push(l),r[2]){for(var f=r[2].split(t),i=0;r&&i<f.length;){for(var d=f[i].replace(/\s+$/,""),p=i+1;p<f.length;++p){var u=f[p];if(!/\s/.test(u[0]))break;d+=u,i=p}if(r=d.match(a)){for(var m={name:r[1],values:[]},h=r[2].split(","),c=0;c<h.length;++c)m.values.push(ltrim(h[c]));if(l.procType)if(l.contentDomain||"Content-Domain"!==m.name)if(l.dekInfo||"DEK-Info"!==m.name)l.headers.push(m);else{if(0===m.values.length)throw Error('Invalid PEM formatted message. The "DEK-Info" header must have at least one subfield.');l.dekInfo={algorithm:h[0],parameters:h[1]||null}}else l.contentDomain=h[0]||"";else{if("Proc-Type"!==m.name)throw Error('Invalid PEM formatted message. The first encapsulated header must be "Proc-Type".');if(2!==m.values.length)throw Error('Invalid PEM formatted message. The "Proc-Type" header must have two subfields.');l.procType={version:h[0],type:h[1]}}}++i}if("ENCRYPTED"===l.procType&&!l.dekInfo)throw Error('Invalid PEM formatted message. The "DEK-Info" header must be present if "Proc-Type" is "ENCRYPTED".')}}if(0===n.length)throw Error("Invalid PEM formatted message.");return n};